avoid to create symlink loops

This commit is contained in:
lilydjwg 2014-02-13 22:12:54 +08:00
parent 2a294ea85b
commit eaf9afc912

View file

@ -28,6 +28,12 @@ logger = logging.getLogger(__name__)
# handles only x86_64, i686 and any arch packages # handles only x86_64, i686 and any arch packages
_pkgfile_pat = re.compile(r'(?:^|/).+-[^-]+-\d+-(?:x86_64|i686|any)\.pkg\.tar\.xz(?:\.sig)?$') _pkgfile_pat = re.compile(r'(?:^|/).+-[^-]+-\d+-(?:x86_64|i686|any)\.pkg\.tar\.xz(?:\.sig)?$')
def same_existent_file(a, b):
try:
return os.path.samefile(path, newpath)
except OSError:
return False
class ActionInfo(archpkg.PkgNameInfo): class ActionInfo(archpkg.PkgNameInfo):
def __new__(cls, path, action, four=None, five=None, pkgpath=None): def __new__(cls, path, action, four=None, five=None, pkgpath=None):
if four is not None: if four is not None:
@ -208,6 +214,7 @@ class EventHandler(pyinotify.ProcessEvent):
def my_init(self, config, wm, ioloop=None): def my_init(self, config, wm, ioloop=None):
self.moved_away = {} self.moved_away = {}
self.repomans = {} self.repomans = {}
# TODO: use a expiring dict
self.our_links = set() self.our_links = set()
self._ioloop = ioloop or IOLoop.instance() self._ioloop = ioloop or IOLoop.instance()
@ -320,12 +327,13 @@ class EventHandler(pyinotify.ProcessEvent):
if self._auto_rename and action == 'add' and act.arch != arch: if self._auto_rename and action == 'add' and act.arch != arch:
newd = os.path.join(base, act.arch) newd = os.path.join(base, act.arch)
newpath = os.path.join(newd, file) newpath = os.path.join(newd, file)
os.rename(path, newpath) if not same_existent_file(path, newpath):
os.rename(path, newpath)
act.path = newpath act.path = newpath
path = newpath path = newpath
arch = act.arch arch = act.arch
d = newd d = newd
if self._symlink_any and act.arch == 'any': if self._symlink_any and act.arch == 'any':
for newarch in ('i686', 'x86_64', 'any'): for newarch in ('i686', 'x86_64', 'any'):
@ -335,12 +343,14 @@ class EventHandler(pyinotify.ProcessEvent):
newd = os.path.join(base, newarch) newd = os.path.join(base, newarch)
newpath = os.path.join(newd, file) newpath = os.path.join(newd, file)
if action == 'add': if action == 'add':
try: oldpath = os.path.join('..', arch, file)
self.our_links.add(newpath) if not same_existent_file(oldpath, newpath):
os.symlink(os.path.join('..', arch, file), newpath) try:
except FileExistsError: self.our_links.add(newpath)
pass os.symlink(oldpath, newpath)
callback(newd, ActionInfo(newpath, action)) except FileExistsError:
pass
callback(newd, ActionInfo(newpath, action))
else: else:
try: try:
os.unlink(newpath) os.unlink(newpath)