Dateianhang 'uidgidfix.py'
Herunterladen 1 #!/usr/bin/env python
2 """
3 Repair damage caused by improper use of rsync (e.g. if you wanted to create a
4 backup copy of a system using a another system with a different uid/gid mapping
5 and you forgot to give --numeric-ids).
6
7 If you still have the correct uid/gids on the original system, you can create
8 a backup of them using (you need to be root, otherwise you might get some
9 permission denied errors and a incomplete list):
10
11 uidgidfix.py backup / > uidgidfix.lst
12
13 You'll get a really long list in uidgidfix.lst then (if you need to start from
14 a different directory than /, then just give that).
15
16 Note: You likely want to review / edit that list before applying it to the
17 damaged copy of the system. This script is NOT foolproof and comes
18 without any warranty - USE IT ON YOUR OWN RISK!
19
20 Testing the contents of uidgidfix.lst on the damaged system works like this:
21
22 uidgidfix.py dryrun < uidgidfix.lst
23
24 It will tell you what it WOULD change, but won't change anything.
25 If you are really sure you want that, run it like this (you need to be root):
26
27 uidgidfix.py restore < uidgidfix.lst
28
29 @copyright: Thomas Waldmann <tw AT waldmann-edv DOT de>
30 @license: GNU GPL v2 or any later version
31 """
32
33 # root:root is likely 0:0 on all systems, so we can skip that:
34 SKIP_ROOT = True
35
36 import os
37 import sys
38 import errno
39
40
41 def backup(outfile, top):
42 """
43 create a uid gid pathname list
44
45 @param outfile: open file to write output to
46 @param top: path to start the recursion
47 """
48 for root, dirs, files in os.walk(top, topdown=False):
49 absroot = os.path.abspath(root)
50 for name in dirs + files:
51 pathname = os.path.join(absroot, name)
52 try:
53 st = os.lstat(pathname)
54 uid = st.st_uid
55 gid = st.st_gid
56 if not (SKIP_ROOT and uid == 0 and gid == 0):
57 outfile.write("%d %d %s\n" % (uid, gid, pathname))
58 except OSError, err:
59 if err.errno != errno.ENOENT:
60 # we raise any exception except if a file just vanished
61 # (happens in /proc usually)
62 raise
63
64
65 def restore(infile, dryrun):
66 """
67 read a uid gid pathname list and fix uid/gid on the local filesystem,
68 if the file exists with a different uid/gid
69
70 @param infile: open file to read list from
71 @param dryrun: if True, do not change filesystem, but just tell about changes
72 """
73 for line in infile:
74 line = line.rstrip('\n')
75 uid, gid, pathname = line.split(' ', 2)
76 uid = int(uid)
77 gid = int(gid)
78 if os.path.lexists(pathname):
79 try:
80 st = os.lstat(pathname)
81 if uid != st.st_uid or gid != st.st_gid:
82 if dryrun:
83 print "%d:%d -> %d:%d %s" % (st.st_uid, st.st_gid, uid, gid, pathname)
84 else:
85 os.lchown(pathname, uid, gid)
86 except OSError, err:
87 print str(err)
88
89
90 if __name__ == '__main__':
91 try:
92 cmd = sys.argv[1]
93 except IndexError:
94 print __doc__
95 else:
96 if cmd == 'backup':
97 try:
98 path = sys.argv[2]
99 except IndexError:
100 path = '.'
101 backup(sys.stdout, path)
102 elif cmd == 'dryrun':
103 restore(sys.stdin, True)
104 elif cmd == 'restore':
105 restore(sys.stdin, False)
Gespeicherte Dateianhänge
Um Dateianhänge in eine Seite einzufügen sollte unbedingt eine Angabe wie attachment:dateiname benutzt werden, wie sie auch in der folgenden Liste der Dateien erscheint. Es sollte niemals die URL des Verweises ("laden") kopiert werden, da sich diese jederzeit ändern kann und damit der Verweis auf die Datei brechen würde.Sie dürfen keine Anhänge an diese Seite anhängen!