1
2 """
3
4 @author: Fabio Erculiani <lxnay@sabayonlinux.org>
5 @contact: lxnay@sabayonlinux.org
6 @copyright: Fabio Erculiani
7 @license: GPL-2
8
9 B{Entropy Package Manager Client Miscellaneous Interface}.
10
11 """
12
13 import os
14 import sys
15 import shutil
16 import subprocess
17 from entropy.client.interfaces import Client
18 from entropy.exceptions import *
19 from entropy.const import etpConst, etpCache
20 from entropy.output import darkred, darkgreen, red, brown, blue
21 from entropy.tools import getstatusoutput
22 from entropy.i18n import _
23
25
36
38 self.scanfs(dcache = True)
39 self.do_backup(key)
40 source_file = etpConst['systemroot'] + self.scandata[key]['source']
41 dest_file = etpConst['systemroot'] + self.scandata[key]['destination']
42 if os.access(source_file, os.R_OK):
43 shutil.move(source_file, dest_file)
44 self.remove_from_cache(key)
45
47 self.scanfs(dcache = True)
48 source_file = etpConst['systemroot'] + self.scandata[key]['source']
49 if os.access(source_file, os.F_OK) and os.access(source_file, os.W_OK):
50 os.remove(source_file)
51 self.remove_from_cache(key)
52
54 self.scanfs(dcache = True)
55 sys_set_plg_id = \
56 etpConst['system_settings_plugins_ids']['client_plugin']
57 files_backup = self.Entropy.SystemSettings[sys_set_plg_id]['misc']['filesbackup']
58 dest_file = etpConst['systemroot'] + self.scandata[key]['destination']
59 if files_backup and os.path.isfile(dest_file):
60 bcount = 0
61 backupfile = etpConst['systemroot'] + \
62 os.path.dirname(self.scandata[key]['destination']) + \
63 "/._entropy_backup." + unicode(bcount) + "_" + \
64 os.path.basename(self.scandata[key]['destination'])
65 while os.path.lexists(backupfile):
66 bcount += 1
67 backupfile = etpConst['systemroot'] + \
68 os.path.dirname(self.scandata[key]['destination']) + \
69 "/._entropy_backup." + unicode(bcount) + "_" + \
70 os.path.basename(self.scandata[key]['destination'])
71 try:
72 shutil.copy2(dest_file, backupfile)
73 except IOError:
74 pass
75
76 - def scanfs(self, dcache = True, quiet = False):
77
78 if dcache:
79
80 if self.scandata != None:
81 return self.scandata
82
83
84 try:
85 z = self.load_cache()
86 if z != None:
87 self.scandata = z
88 return self.scandata
89 except (CacheCorruptionError, KeyError, IOError, OSError,):
90 pass
91
92 scandata = {}
93 counter = 0
94 name_cache = set()
95 client_conf_protect = self.Entropy.get_system_config_protect()
96
97 for path in client_conf_protect:
98
99
100 path = path.encode(sys.getfilesystemencoding())
101
102 scanfile = False
103 if os.path.isfile(path):
104
105 path = os.path.dirname(path)
106 scanfile = True
107
108 for currentdir,subdirs,files in os.walk(path):
109 for item in files:
110
111 if scanfile:
112 if path != item:
113 continue
114
115 filepath = os.path.join(currentdir,item)
116 if item.startswith("._cfg"):
117
118
119 number = item[5:9]
120 try:
121 int(number)
122 except ValueError:
123 continue
124 if item[9] != "_":
125 continue
126
127 if filepath in name_cache:
128 continue
129 name_cache.add(filepath)
130
131 mydict = self.generate_dict(filepath)
132 if mydict['automerge']:
133 if not quiet:
134 mytxt = _("Automerging file")
135 self.Entropy.updateProgress(
136 darkred("%s: %s") % (
137 mytxt,
138 darkgreen(etpConst['systemroot'] + mydict['source']),
139 ),
140 importance = 0,
141 type = "info"
142 )
143 if os.path.isfile(etpConst['systemroot']+mydict['source']):
144 try:
145 os.rename(etpConst['systemroot']+mydict['source'],
146 etpConst['systemroot']+mydict['destination'])
147 except (OSError, IOError,), e:
148 if not quiet:
149 mytxt = "%s :: %s: %s. %s: %s" % (
150 red(_("System Error")),
151 red(_("Cannot automerge file")),
152 brown(etpConst['systemroot'] + mydict['source']),
153 blue("error"),
154 e,
155 )
156 self.Entropy.updateProgress(
157 mytxt,
158 importance = 1,
159 type = "warning"
160 )
161 continue
162 else:
163 counter += 1
164 scandata[counter] = mydict.copy()
165
166 if not quiet:
167 try:
168 self.Entropy.updateProgress(
169 "("+blue(str(counter))+") " + red(" file: ") + \
170 os.path.dirname(filepath) + "/" + os.path.basename(filepath)[10:],
171 importance = 1,
172 type = "info"
173 )
174 except:
175 pass
176
177 self.Cacher.push(etpCache['configfiles'],scandata)
178 self.scandata = scandata.copy()
179 return scandata
180
182 sd = self.Cacher.pop(etpCache['configfiles'])
183 if not isinstance(sd,dict):
184 raise CacheCorruptionError("CacheCorruptionError")
185
186 try:
187 name_cache = set()
188
189 for x in sd:
190 mysource = sd[x]['source']
191
192 if mysource in name_cache:
193 sd.pop(x)
194 continue
195 if not os.path.isfile(etpConst['systemroot']+mysource):
196 raise CacheCorruptionError("CacheCorruptionError")
197 name_cache.add(mysource)
198
199 return sd
200 except (KeyError,EOFError,IOError,):
201 raise CacheCorruptionError("CacheCorruptionError")
202
204 self.scanfs(dcache = True, quiet = quiet)
205 keys = self.scandata.keys()
206 try:
207 for key in keys:
208 if self.scandata[key]['source'] == filepath[len(etpConst['systemroot']):]:
209 del self.scandata[key]
210 except:
211 pass
212
213 if keys:
214 keys = sorted(keys)
215 index = keys[-1]
216 else:
217 index = 0
218 index += 1
219 mydata = self.generate_dict(filepath)
220 self.scandata[index] = mydata.copy()
221 self.Cacher.push(etpCache['configfiles'],self.scandata)
222
224 self.scanfs(dcache = True)
225 try:
226 del self.scandata[key]
227 except:
228 pass
229 self.Cacher.push(etpCache['configfiles'],self.scandata)
230 return self.scandata
231
233
234 item = os.path.basename(filepath)
235 currentdir = os.path.dirname(filepath)
236 tofile = item[10:]
237 number = item[5:9]
238 try:
239 int(number)
240 except:
241 mytxt = _("Invalid config file number")
242 raise InvalidDataType("InvalidDataType: %s '0000->9999'." % (mytxt,))
243 tofilepath = currentdir+"/"+tofile
244 mydict = {}
245 mydict['revision'] = number
246 mydict['destination'] = tofilepath[len(etpConst['systemroot']):]
247 mydict['source'] = filepath[len(etpConst['systemroot']):]
248 mydict['automerge'] = False
249 if not os.path.isfile(tofilepath):
250 mydict['automerge'] = True
251 if (not mydict['automerge']):
252
253 try:
254 if not os.path.lexists(filepath):
255 return mydict
256 if os.path.islink(filepath):
257
258 if not os.path.exists(filepath):
259 return mydict
260 result = getstatusoutput('diff -Nua "%s" "%s" | grep "^[+-][^+-]" | grep -v \'# .Header:.*\'' % (filepath,tofilepath,))[1]
261 if not result:
262 mydict['automerge'] = True
263 except:
264 pass
265
266 if (not mydict['automerge']):
267 try:
268 if not os.path.lexists(filepath):
269 return mydict
270 if os.path.islink(filepath):
271
272 if not os.path.exists(filepath):
273 return mydict
274 result = subprocess.call('diff -Bbua "%s" "%s" | egrep \'^[+-]\' | egrep -v \'^[+-][\t ]*#|^--- |^\+\+\+ \' | egrep -qv \'^[-+][\t ]*$\'' % (filepath,tofilepath,), shell = True)
275 if result == 1:
276 mydict['automerge'] = True
277 except:
278 pass
279 return mydict
280