1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import os
20 import os.path
21 import sys
22 import fnmatch
23 import pwd
24 import grp
25 import gettext
26 import locale
27 import errno
28 import random
29 from config import *
30
31
32 EXIT_CODE_NORMAL = 0
33 EXIT_CODE_FATAL = 1
34 EXIT_CODE_RECOVERABLE = 2
35 EXIT_CODE_NO_USER_PROFILE = 3
36
37 _util_admin_log_config_filename = None
38 _util_readable_log_config_filename = None
39
46
53
55 """Returns the filename that the program actually used to read the log configuration,
56 as stored with set_readable_log_config_filename(). This may be different from the
57 filename from get_admin_log_config_filename(), since the helper processes in Sabayon
58 may need to be given a temporary file to read their log configuration (as root's
59 human-readable file may not be readable by the helper processes)."""
60 global _util_readable_log_config_filename
61 return _util_readable_log_config_filename
62
64 """Stores the filename that the program actually used to read the log configuration.
65 This can be queried back with get_readable_log_config_filename(). This may be different from the
66 filename from get_admin_log_config_filename(), since the helper processes in Sabayon
67 may need to be given a temporary file to read their log configuration (as root's
68 human-readable file may not be readable by the helper processes)."""
69 global _util_readable_log_config_filename
70 _util_readable_log_config_filename = str
71
75
76 unit_tests_homedir = None
80
82 if unit_tests_homedir:
83 return unit_tests_homedir
84 try:
85 pw = pwd.getpwuid (os.getuid ())
86 if pw.pw_dir != "":
87 return pw.pw_dir
88 except KeyError:
89 pass
90
91 if os.environ.has_key ("HOME"):
92 return os.environ["HOME"]
93 else:
94 raise GeneralError (_("Cannot find home directory: not set in /etc/passwd and no value for $HOME in environment"))
95
97 """Returns a list of non-primary, non-system groups that the user belongs
98 to. Raises a GeneralError if this fails. May return an empty list.
99 """
100
101 groups = grp.getgrall()
102
103 try:
104 pw = pwd.getpwuid (os.getuid ())
105 user = pw[0]
106 except KeyError:
107 if os.environ.has_key("USER"):
108 user = os.environ["USER"]
109 else:
110 raise GeneralError (_("Cannot find username: not set in /etc/passwd and no value for $USER in environment"))
111
112 members = []
113
114 for group in groups:
115 if group[0] in members:
116 continue
117 if group[2] < 500:
118 continue
119 if group[0] == user:
120 continue
121 if user in group[3]:
122 members.append(group[0])
123
124 return members
125
127 try:
128 pw = pwd.getpwuid (os.getuid ())
129 if pw.pw_name != "":
130 return pw.pw_name
131 except KeyError:
132 pass
133
134 if os.environ.has_key ("USER"):
135 return os.environ["USER"]
136 else:
137 raise GeneralError (_("Cannot find username: not set in /etc/passwd and no value for $USER in environment"))
138
140 import traceback
141 import sys
142 traceback.print_exc(file=sys.stderr)
143
145 """Binds _() to gettext.gettext() in the global namespace. Run
146 util.init_gettext() at the entry point to any script and you'll be
147 able to use _(), gettext(), and ngettext() to mark strings for
148 translation."""
149 try:
150 locale.setlocale (locale.LC_ALL, "")
151 except locale.Error:
152 pass
153 gettext.install (PACKAGE, LOCALEDIR)
154
155 import __builtin__
156 __builtin__.__dict__['gettext'] = __builtin__.__dict__['_']
157 __builtin__.__dict__['ngettext'] = gettext.ngettext
158
160 """Returns a string with random binary data of the specified length"""
161 bin = ""
162 while len > 0:
163 len = len - 1
164 bin = bin + chr(random.getrandbits(8))
165 return bin
166
167
169 '''Given a path split it into a head and tail. If head is passed then
170 it is assumed to comprise the first part of the full path. If tail is
171 passed it is assumed to comprise the second part of the full path.
172 The path, head, and tail are made canonical via os.path.normpath prior
173 to the operations. ValueErrors are raised if head is not present at the
174 start of the path or if the path does not end with tail. The split must
175 occur on a directory separator boundary.
176
177 The return value is the tuple (head, tail) in canonical form.'''
178 path = os.path.normpath(path)
179
180 if tail is not None:
181 tail = os.path.normpath(tail)
182 if tail[0] == '/':
183 tail = tail[1:]
184 if not path.endswith(tail):
185 raise ValueError
186 path_len = len (path)
187 tail_len = len (tail)
188 dir_split = path_len - tail_len - 1
189 if path[dir_split] != '/':
190 raise ValueError
191 return (path[:dir_split], path[dir_split+1:])
192
193 if head is not None:
194 head = os.path.normpath(head)
195 if head[-1] == '/':
196 head = head[:-1]
197 if not path.startswith(head):
198 raise ValueError
199 head_len = len (head)
200 dir_split = head_len
201 if path[dir_split] != '/':
202 raise ValueError
203 return (path[:dir_split], path[dir_split+1:])
204
205 raise ValueError
206
215
216
217
220 self.a = a
221 self.b = b
222
224 ''' Given two dictionaries a,b analyze them for their
225 differences and similarities.
226
227 intersection - keys shared between a and b
228 only_a - keys only present in a
229 only_b - keys only present in b
230 equal - keys present in both a and b whole values are equal
231 not_equal - keys present in both a and b whole values are not equal'''
232
233 self.keys_a = self.a.keys()
234 self.keys_b = self.b.keys()
235
236 self.intersection = []
237 self.only_a = []
238 self.only_b = []
239 self.equal = []
240 self.not_equal = []
241 self._add = {}
242 self._del = {}
243 self._mod = {}
244
245 for k in self.keys_a:
246 if self.b.has_key(k):
247 self.intersection.append(k)
248 else:
249 self.only_a.append(k)
250
251 for k in self.keys_b:
252 if not self.a.has_key(k):
253 self.only_b.append(k)
254
255 for k in self.intersection:
256 if self.a[k] == self.b[k]:
257 self.equal.append(k)
258 else:
259 self.not_equal.append(k)
260
262 'return list of keys shared between a and b'
263 return self.intersection
264
266 'return list of keys only present in a'
267 return self.only_a
268
270 'return list of keys only present in b'
271 return self.only_b
272
274 'return list of keys present in both a and b whole values are equal'
275 return self.equal
276
278 'return list of keys present in both a and b whole values are not equal'
279 return self.not_equal
280
282 '''Return changes necessary to make dict_lhs equivalent to dict_rhs,
283 (e.g. lhs = rhs), the two dictionary parameters are specified as
284 either the string 'a' or the string 'b' corresponding to the parameters
285 this class was created with.
286
287 Return value is a dictionary with 3 keys (add, del, mod) whose values
288 are dictionaries containing containing (key,value) pairs to add,
289 delete, or modify respectively in dict_lhs.'''
290
291 if dict_lhs == dict_rhs or dict_lhs not in "ab" or dict_rhs not in "ab":
292 raise ValueError
293
294 if dict_lhs == 'a':
295 a = self.a
296 b = self.b
297 only_a = self.only_a
298 only_b = self.only_b
299 elif dict_lhs == 'b':
300 a = self.b
301 b = self.a
302 only_a = self.only_b
303 only_b = self.only_a
304 else:
305 raise ValueError
306
307 self._add = {}
308 for k in only_b:
309 self._add[k] = b[k]
310
311 self._del = {}
312 for k in only_a:
313 self._del[k] = a[k]
314
315 self._mod = {}
316 for k in self.not_equal:
317 self._mod[k] = b[k]
318
319 change_set = {'add':self._add, 'del':self._del, 'mod':self._mod}
320 return change_set
321
322
324 if len(self.only_a) == 0 and len(self.only_b) == 0 and len(self.not_equal) == 0:
325 return True
326 else:
327 return False
328
330 'Print the results of the dictionary comparision'
331 print "intersection = %s" % ",".join(self.intersection)
332 print "only a = %s" % ",".join(self.only_a)
333 print "only b = %s" % ",".join(self.only_b)
334 print "equal = %s" % ",".join(self.equal)
335 print "not equal = %s" % ",".join(self.not_equal)
336
338 _add = cs['add']
339 _del = cs['del']
340 _mod = cs['mod']
341
342 if len(_add.keys()):
343 print "Key/Values to ADD"
344 for k in _add.keys():
345 print " %s=%s" % (k, _add[k])
346
347 if len(_del.keys()):
348 print "Keys to DELETE"
349 for k in _del.keys():
350 print " %s=%s" % (k, _del[k])
351
352 if len(_mod.keys()):
353 print "Key/Values to Modify"
354 for k in _mod.keys():
355 print " %s=%s" % (k, _mod[k])
356
357
359 dir = os.path.normpath (dir)
360
361 for ignore_dir in ignore_dir_list:
362 ignore_path = os.path.normpath (os.path.join (base_dir, ignore_dir))
363
364 if fnmatch.fnmatch (dir, ignore_path):
365 return True
366
367 parent = os.path.dirname (dir)
368 if parent != dir:
369 return should_ignore_dir (base_dir, ignore_dir_list, parent)
370 else:
371 return False
372
374 file = os.path.normpath (file)
375
376 for ignore_file in ignore_file_list:
377 ignore_path = os.path.normpath (os.path.join (base_dir, ignore_file))
378
379 if fnmatch.fnmatch (file, ignore_path):
380 return True
381
382 return should_ignore_dir (base_dir, ignore_dir_list, os.path.dirname (file))
383