1#! /usr/bin/env python3 2 3# mkreal 4# 5# turn a symlink to a directory into a real directory 6 7import sys 8import os 9from stat import * 10 11join = os.path.join 12 13error = 'mkreal error' 14 15BUFSIZE = 32*1024 16 17def mkrealfile(name): 18 st = os.stat(name) # Get the mode 19 mode = S_IMODE(st[ST_MODE]) 20 linkto = os.readlink(name) # Make sure again it's a symlink 21 f_in = open(name, 'r') # This ensures it's a file 22 os.unlink(name) 23 f_out = open(name, 'w') 24 while 1: 25 buf = f_in.read(BUFSIZE) 26 if not buf: break 27 f_out.write(buf) 28 del f_out # Flush data to disk before changing mode 29 os.chmod(name, mode) 30 31def mkrealdir(name): 32 st = os.stat(name) # Get the mode 33 mode = S_IMODE(st[ST_MODE]) 34 linkto = os.readlink(name) 35 files = os.listdir(name) 36 os.unlink(name) 37 os.mkdir(name, mode) 38 os.chmod(name, mode) 39 linkto = join(os.pardir, linkto) 40 # 41 for filename in files: 42 if filename not in (os.curdir, os.pardir): 43 os.symlink(join(linkto, filename), join(name, filename)) 44 45def main(): 46 sys.stdout = sys.stderr 47 progname = os.path.basename(sys.argv[0]) 48 if progname == '-c': progname = 'mkreal' 49 args = sys.argv[1:] 50 if not args: 51 print('usage:', progname, 'path ...') 52 sys.exit(2) 53 status = 0 54 for name in args: 55 if not os.path.islink(name): 56 print(progname+':', name+':', 'not a symlink') 57 status = 1 58 else: 59 if os.path.isdir(name): 60 mkrealdir(name) 61 else: 62 mkrealfile(name) 63 sys.exit(status) 64 65if __name__ == '__main__': 66 main() 67