294
# FIXME: This method works around shortcomings in tarfile.extract().
295
# Once tarfile can reliably extract symlinked data, this method
296
# should be removed; all calls to it will become unnecessary.
297
def _readSymbolicPath(self, tarfile, path):
298
""" converts a path with symbolic links to an non-linked one """
299
member_paths = tarfile.getnames()
302
# go through all directories/files from top to bottom.
303
for path_element in path.split('/'):
304
# tentatively add the current element to the return path
305
next_path = os.path.join(return_path, path_element)
306
if next_path not in member_paths:
307
raise Exception('tar does not contain %s' % next_path)
308
# now see if it's symbolic
309
next_member = tarfile.getmember(next_path)
310
if next_member.issym():
311
# if it is, discard the new element, and add its linked path
312
next_path = os.path.join(return_path, next_member.linkpath)
313
# now resolve all '..' references
315
for element in next_path.split('/'):
317
next_path_stack.pop()
319
next_path_stack.append(element)
320
next_path = '/'.join(next_path_stack)
321
# ensure we are not caught in an infinite symlink cycle
322
if (time.time() - start) > 2:
323
logging.warn('symlink cycle in %s' % tarfile.name)
325
# update the return path
326
return_path = next_path
293
329
def extract_icon(self, tarfile, iconName, newIconName):
294
330
logging.info("extract_icon: %s %s %s" % (tarfile.name, iconName, newIconName))
295
331
extractName = iconName
296
332
if iconName.startswith('/'):
297
333
extractName = ".%s" % iconName
335
extractName = self._readSymbolicPath(tarfile, extractName)
299
336
iconFile = tarfile.extractfile(extractName)
300
337
outicon = open(newIconName, "w")
301
338
outicon.write(iconFile.read())