"Module handling"
# pylint: disable-msg=W0403
import re
from .Conf import Conf, odict, BadFile, VersionMismatch
class ConfModules(Conf):
"""ConfModules(Conf)
This reads /etc/modprobe.d/network.conf into a dictionary keyed on device type,
holding dictionaries: cm['eth0']['alias'] --> 'smc-ultra'
cm['eth0']['options'] --> {'io':'0x300', 'irq':'10'}
cm['eth0']['post-install'] --> ['/bin/foo', 'arg1',
'arg2']
path[*] entries are ignored (but not removed)
New entries are added at the end to make sure that they
come after any path[*] entries.
Comments are delimited by initial '#'
"""
def __init__(self, filename = '/etc/modprobe.d/network.conf'):
Conf.__init__(self, filename, '#', '\t ', ' ')
def read(self):
Conf.read(self)
self.initvars()
def initvars(self):
# pylint: disable-msg=W0201
self.vars = odict()
keys = ('alias', 'options', 'install', 'remove')
self.rewind()
while self.findnextcodeline():
var = self.getfields()
# strip comments
for val in var:
if val and val.strip().startswith('#'):
var = var[:var.index(val)]
break
# assume no -k field
if len(var) > 2 and var[0] in keys:
if not self.vars.has_key(var[1]):
self.vars[var[1]] = odict({'alias':'',
'options':odict(), 'install':[], 'remove':[]})
if not cmp(var[0], 'alias'):
self.vars[var[1]]['alias'] = var[2]
elif not cmp(var[0], 'options'):
self.vars[var[1]]['options'] = self.splitoptlist(var[2:])
elif not cmp(var[0], 'install'):
self.vars[var[1]]['install'] = var[2:]
elif not cmp(var[0], 'remove'):
self.vars[var[1]]['remove'] = var[2:]
self.nextline()
self.rewind()
def splitoptlist(self, optlist):
mdict = odict()
for opt in optlist:
optup = self.splitopt(opt)
if optup:
mdict[optup[0]] = optup[1]
return mdict
def splitopt(self, opt):
eq = opt.find('=')
if eq > 0:
return (opt[:eq], opt[eq+1:])
else:
return ()
def joinoptlist(self, mdict):
optstring = ''
for key in mdict.keys():
optstring = optstring + key + '=' + mdict[key] + ' '
return optstring
def __getitem__(self, varname):
if self.vars.has_key(varname):
return self.vars[varname]
else:
return odict()
def _quote(self, s):
s = s.replace('\\', '\\\\')
s = s.replace('*', '\\*')
s = s.replace('?', '\\?')
s = s.replace('.', '\\.')
s = s.replace('(', '\\(')
s = s.replace(')', '\\)')
s = s.replace('^', '\\^')
s = s.replace('$', '\\$')
return s
def __setitem__(self, varname, value):
# set *every* instance (should only be one, but...) to avoid surprises
place = self.tell()
self.vars[varname] = value
endofline = ""
replace = ""
for key in value.keys():
self.rewind()
missing = 1
findexp = str('^[\t ]*%s[\t ]+%s[\t ]+' %
(self._quote(key), self._quote(varname)))
if not cmp(key, 'alias'):
endofline = value[key]
replace = key + ' ' + varname + ' ' + endofline
elif not cmp(key, 'options'):
endofline = self.joinoptlist(value[key])
replace = key + ' ' + varname + ' ' + endofline
elif not cmp(key, 'install'):
endofline = ' '.join(value[key])
replace = key + ' ' + varname + ' ' + endofline
elif not cmp(key, 'remove'):
endofline = ' '.join(value[key])
replace = key + ' ' + varname + ' ' + endofline
else:
endofline = ""
replace = ""
# some idiot apparently put an unrecognized key in
# the dictionary; ignore it...
continue
# FIXED: [146291] GUI adds trailing spaces to "options" lines
# in /etc/modprobe.conf when adding/deleting wireless devices
replace = replace.rstrip()
if endofline:
# there's something to write...
while self.findnextline(findexp):
cl = self.getline().split(' #')
if len(cl) >= 2:
comment = " #".join(cl[1:])
self.setline(replace + ' #' + comment)
else:
self.setline(replace)
missing = 0
self.nextline()
if missing:
self.fsf()
self.insertline(replace)
else:
# delete any instances of this if they exist.
while self.findnextline(findexp):
self.deleteline()
self.seek(place)
def __delitem__(self, varname):
# delete *every* instance...
place = self.tell()
for key in self.vars[varname].keys():
self.rewind()
while self.findnextline('^[\t ]*'
+ key
+ '([\t ]-k)?[\t ]+'
+ varname):
self.deleteline()
del self.vars[varname]
self.seek(place)
def write(self):
# need to make sure everything is set, because program above may
# well have done cm['eth0']['post-install'] = ['/bin/foo', '-f',
# '/tmp/bar']
# which is completely reasonable, but won't invoke __setitem__
for key in self.vars.keys():
self[key] = self.vars[key]
Conf.write(self)
def keys(self):
return self.vars.keys()
def has_key(self, key):
return self.vars.has_key(key)
class ConfModInfo(Conf):
"""ConfModInfo(Conf)
This READ-ONLY class reads /boot/module-info.
The first line of /boot/module-info is "Version