# Back In Time
# Copyright (C) 2008-2022 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 configfile
import sys
import tools
#TODO: rewrite and finally USE this
[docs]
class DriveInfo(configfile.ConfigFile):
def __init__(self, path):
configfile.ConfigFile.__init__(self)
self.path = path
self.load(self._get_driveinfo_file_())
dirty = False
if sys.platform == 'win32':
#there is nothing to do
pass
else:
if not self.hasKey('hardlinks'):
self.setBoolValue('hardlinks', self._check_hardlinks_())
dirty = True
if not self.hasKey('permissions'):
self.setBoolValue('permissions', self._check_perms_())
dirty = True
if not self.hasKey('usergroup'):
self.setBoolValue('usergroup', self._check_usergroup_())
dirty = True
if dirty:
self.save(self._get_driveinfo_file_())
[docs]
def support_hardlinks(self):
return self.boolValue('hardlinks', False)
[docs]
def support_permissions(self):
return self.boolValue('permissions', False)
[docs]
def support_usergroup(self):
return self.boolValue('usergroup', False)
def _get_driveinfo_file_(self):
return os.path.join(self.path, 'driveinfo')
def _check_hardlinks_(self):
tmp_path = os.path.join(self.path, 'driveinfo.tmp')
tools.makeDirs(tmp_path)
if not os.path.isdir(tmp_path):
return False
file1_path = os.path.join(tmp_path, 'file1')
file2_path = os.path.join(tmp_path, 'file2')
ret_val = False
os.system("echo abc > \"%s\"" % file1_path)
os.system("ln \"%s\" \"%s\"" % (file1_path, file2_path))
os.system("echo abc > \"%s\"" % file2_path)
if os.path.exists(file1_path) and os.path.exists(file2_path):
try:
info1 = os.stat(file1_path)
info2 = os.stat(file2_path)
if info1.st_size == info2.st_size:
ret_val = True
except:
pass
os.system("rm -rf \"%s\"" % tmp_path)
return ret_val
def _check_perms_for_file_(self, file_path, mode):
ret_val = False
os.system("chmod %s \"%s\"" % (mode, file_path))
try:
info = "%o" % os.stat(file_path).st_mode
info = info[-3 :]
if info == mode:
ret_val = True
except:
pass
return ret_val
def _check_perms_(self):
tmp_path = os.path.join(self.path, 'driveinfo.tmp')
tools.makeDirs(tmp_path)
if not os.path.isdir(tmp_path):
return False
file_path = os.path.join(tmp_path, 'file')
os.system("echo abc > \"%s\"" % file_path)
if not os.path.isfile(file_path):
return False
ret_val = False
if self._check_perms_for_file_(file_path, '111'):
if self._check_perms_for_file_(file_path, '700'):
if self._check_perms_for_file_(file_path, '600'):
if self._check_perms_for_file_(file_path, '711'):
if self._check_perms_for_file_(file_path, '300'):
if self._check_perms_for_file_(file_path, '666'):
ret_val = True
os.system("rm -rf \"%s\"" % tmp_path)
return ret_val
def _check_usergroup_(self):
tmp_path = os.path.join(self.path, 'driveinfo.tmp')
tools.makeDirs(tmp_path)
if not os.path.isdir(tmp_path):
return False
file_path = os.path.join(tmp_path, 'file')
os.system("echo abc > \"%s\"" % file_path)
if not os.path.isfile(file_path):
return False
ret_val = False
uid = os.getuid()
gid = os.getgid()
try:
info = os.stat(file_path)
if info.st_uid == uid and info.st_gid == gid:
ret_val = True
except:
pass
if ret_val and uid == 0:
#try to change the group
import grp
#search for another group
new_gid = gid
new_name = ''
for group in grp.getgrall():
if group.gr_gid != gid:
new_gid = group.gr_gid
new_name = group.gr_name
break
if new_gid != gid:
os.system("chgrp %s \"%s\"" % (new_name, file_path))
try:
info = os.stat(file_path)
if info.st_gid != new_gid:
ret_val = False
except:
ret_val = False
os.system("rm -rf \"%s\"" % tmp_path)
return ret_val