39 self.debugflag = debug |
39 self.debugflag = debug |
40 self.interactive = interactive |
40 self.interactive = interactive |
41 self.traceback = traceback |
41 self.traceback = traceback |
42 self.trusted_users = {} |
42 self.trusted_users = {} |
43 self.trusted_groups = {} |
43 self.trusted_groups = {} |
|
44 # if ucdata is not None, its keys must be a superset of cdata's |
44 self.cdata = util.configparser() |
45 self.cdata = util.configparser() |
|
46 self.ucdata = None |
45 self.readconfig(util.rcpath()) |
47 self.readconfig(util.rcpath()) |
46 self.updateopts(verbose, debug, quiet, interactive) |
48 self.updateopts(verbose, debug, quiet, interactive) |
47 else: |
49 else: |
48 # parentui may point to an ui object which is already a child |
50 # parentui may point to an ui object which is already a child |
49 self.parentui = parentui.parentui or parentui |
51 self.parentui = parentui.parentui or parentui |
50 self.readhooks = self.parentui.readhooks[:] |
52 self.readhooks = self.parentui.readhooks[:] |
51 self.trusted_users = parentui.trusted_users.copy() |
53 self.trusted_users = parentui.trusted_users.copy() |
52 self.trusted_groups = parentui.trusted_groups.copy() |
54 self.trusted_groups = parentui.trusted_groups.copy() |
53 self.cdata = dupconfig(self.parentui.cdata) |
55 self.cdata = dupconfig(self.parentui.cdata) |
|
56 if self.parentui.ucdata: |
|
57 self.ucdata = dupconfig(self.parentui.ucdata) |
54 if self.parentui.overlay: |
58 if self.parentui.overlay: |
55 self.overlay = dupconfig(self.parentui.overlay) |
59 self.overlay = dupconfig(self.parentui.overlay) |
56 |
60 |
57 def __getattr__(self, key): |
61 def __getattr__(self, key): |
58 return getattr(self.parentui, key) |
62 return getattr(self.parentui, key) |
179 self.trusted_groups[group] = 1 |
206 self.trusted_groups[group] = 1 |
180 |
207 |
181 def setconfig(self, section, name, value): |
208 def setconfig(self, section, name, value): |
182 if not self.overlay: |
209 if not self.overlay: |
183 self.overlay = util.configparser() |
210 self.overlay = util.configparser() |
184 for cdata in (self.overlay, self.cdata): |
211 for cdata in (self.overlay, self.cdata, self.ucdata): |
|
212 if not cdata: continue |
185 if not cdata.has_section(section): |
213 if not cdata.has_section(section): |
186 cdata.add_section(section) |
214 cdata.add_section(section) |
187 cdata.set(section, name, value) |
215 cdata.set(section, name, value) |
188 self.fixconfig(section, name, value) |
216 self.fixconfig(section, name, value) |
189 |
217 |
190 def _config(self, section, name, default, funcname): |
218 def _get_cdata(self, untrusted): |
191 if self.cdata.has_option(section, name): |
219 if untrusted and self.ucdata: |
|
220 return self.ucdata |
|
221 return self.cdata |
|
222 |
|
223 def _config(self, section, name, default, funcname, untrusted, abort): |
|
224 cdata = self._get_cdata(untrusted) |
|
225 if cdata.has_option(section, name): |
192 try: |
226 try: |
193 func = getattr(self.cdata, funcname) |
227 func = getattr(cdata, funcname) |
194 return func(section, name) |
228 return func(section, name) |
195 except ConfigParser.InterpolationError, inst: |
229 except ConfigParser.InterpolationError, inst: |
196 raise util.Abort(_("Error in configuration section [%s] " |
230 msg = _("Error in configuration section [%s] " |
197 "parameter '%s':\n%s") |
231 "parameter '%s':\n%s") % (section, name, inst) |
198 % (section, name, inst)) |
232 if abort: |
|
233 raise util.Abort(msg) |
|
234 self.warn(_("Ignored: %s\n") % msg) |
199 return default |
235 return default |
200 |
236 |
201 def config(self, section, name, default=None): |
237 def _configcommon(self, section, name, default, funcname, untrusted): |
202 return self._config(section, name, default, 'get') |
238 value = self._config(section, name, default, funcname, |
203 |
239 untrusted, abort=True) |
204 def configbool(self, section, name, default=False): |
240 if self.debugflag and not untrusted and self.ucdata: |
205 return self._config(section, name, default, 'getboolean') |
241 uvalue = self._config(section, name, None, funcname, |
206 |
242 untrusted=True, abort=False) |
207 def configlist(self, section, name, default=None): |
243 if uvalue is not None and uvalue != value: |
|
244 self.warn(_("Ignoring untrusted configuration option " |
|
245 "%s.%s = %s\n") % (section, name, uvalue)) |
|
246 return value |
|
247 |
|
248 def config(self, section, name, default=None, untrusted=False): |
|
249 return self._configcommon(section, name, default, 'get', untrusted) |
|
250 |
|
251 def configbool(self, section, name, default=False, untrusted=False): |
|
252 return self._configcommon(section, name, default, 'getboolean', |
|
253 untrusted) |
|
254 |
|
255 def configlist(self, section, name, default=None, untrusted=False): |
208 """Return a list of comma/space separated strings""" |
256 """Return a list of comma/space separated strings""" |
209 result = self.config(section, name) |
257 result = self.config(section, name, untrusted=untrusted) |
210 if result is None: |
258 if result is None: |
211 result = default or [] |
259 result = default or [] |
212 if isinstance(result, basestring): |
260 if isinstance(result, basestring): |
213 result = result.replace(",", " ").split() |
261 result = result.replace(",", " ").split() |
214 return result |
262 return result |
215 |
263 |
216 def has_config(self, section): |
264 def has_config(self, section, untrusted=False): |
217 '''tell whether section exists in config.''' |
265 '''tell whether section exists in config.''' |
218 return self.cdata.has_section(section) |
266 cdata = self._get_cdata(untrusted) |
219 |
267 return cdata.has_section(section) |
220 def configitems(self, section): |
268 |
|
269 def _configitems(self, section, untrusted, abort): |
221 items = {} |
270 items = {} |
222 if self.cdata.has_section(section): |
271 cdata = self._get_cdata(untrusted) |
|
272 if cdata.has_section(section): |
223 try: |
273 try: |
224 items.update(dict(self.cdata.items(section))) |
274 items.update(dict(cdata.items(section))) |
225 except ConfigParser.InterpolationError, inst: |
275 except ConfigParser.InterpolationError, inst: |
226 raise util.Abort(_("Error in configuration section [%s]:\n%s") |
276 msg = _("Error in configuration section [%s]:\n" |
227 % (section, inst)) |
277 "%s") % (section, inst) |
|
278 if abort: |
|
279 raise util.Abort(msg) |
|
280 self.warn(_("Ignored: %s\n") % msg) |
|
281 return items |
|
282 |
|
283 def configitems(self, section, untrusted=False): |
|
284 items = self._configitems(section, untrusted=untrusted, abort=True) |
|
285 if self.debugflag and not untrusted and self.ucdata: |
|
286 uitems = self._configitems(section, untrusted=True, abort=False) |
|
287 keys = uitems.keys() |
|
288 keys.sort() |
|
289 for k in keys: |
|
290 if uitems[k] != items.get(k): |
|
291 self.warn(_("Ignoring untrusted configuration option " |
|
292 "%s.%s = %s\n") % (section, k, uitems[k])) |
228 x = items.items() |
293 x = items.items() |
229 x.sort() |
294 x.sort() |
230 return x |
295 return x |
231 |
296 |
232 def walkconfig(self): |
297 def walkconfig(self, untrusted=False): |
233 sections = self.cdata.sections() |
298 cdata = self._get_cdata(untrusted) |
|
299 sections = cdata.sections() |
234 sections.sort() |
300 sections.sort() |
235 for section in sections: |
301 for section in sections: |
236 for name, value in self.configitems(section): |
302 for name, value in self.configitems(section, untrusted): |
237 yield section, name, value.replace('\n', '\\n') |
303 yield section, name, value.replace('\n', '\\n') |
238 |
304 |
239 def extensions(self): |
305 def extensions(self): |
240 result = self.configitems("extensions") |
306 result = self.configitems("extensions") |
241 for i, (key, value) in enumerate(result): |
307 for i, (key, value) in enumerate(result): |