1
1
# Support for scanning init scripts for LSB info
5
FACILITIES = '/var/lib/lsb/facilities'
3
import re, sys, os, cStringIO
11
class RFC822Parser(dict):
12
"A dictionary-like object."
13
__linere = re.compile(r'([^:]+):\s*(.*)$')
15
def __init__(self, fileob=None, strob=None, startcol=0, basedict=None):
16
if not fileob and not strob:
17
raise ValueError, 'need a file or string'
21
super(RFC822Parser, self).__init__(basedict)
24
fileob = cStringIO.StringIO(strob)
29
line = line[startcol:]
38
self[key] += '\n' + line.strip()
41
m = self.__linere.match(line)
43
# Not a valid RFC822 header
45
key, value = m.groups()
46
self[key] = value.strip()
50
LSBLIB = '/var/lib/lsb'
51
FACILITIES = os.path.join(LSBLIB, 'facilities')
52
DEPENDS = os.path.join(LSBLIB, 'depends')
7
54
beginre = re.compile(re.escape('### BEGIN INIT INFO'))
8
55
endre = re.compile(re.escape('### END INIT INFO'))
9
linere = re.compile(r'\#\s+([^:]+):\s*(.*)')
56
#linere = re.compile(r'\#\s+([^:]+):\s*(.*)')
11
58
def scan_initfile(initfile):
12
headers = {'Description': []}
15
for line in open(initfile).xreadlines():
62
for line in file(initfile):
16
63
line = line.rstrip()
17
64
if beginre.match(line):
20
67
elif scanning and endre.match(line):
29
if line[1:3] == ' ' or line[1] == '\t':
30
headers['Description'].append(line[1:].strip())
33
match = linere.match(line)
35
print >> sys.stderr, "Warning: ignoring invalid init info line"
36
print >> sys.stderr, "-> %s" % line
39
header, body = match.groups()
40
if header == "Description":
41
headers[header].append(body.strip())
42
elif header in ('Default-Start', 'Default-Stop'):
73
if line.startswith('# '):
74
headerlines += line[2:] + '\n'
75
elif line.startswith('#\t'):
76
headerlines += line[1:] + '\n'
78
inheaders = RFC822Parser(strob=headerlines)
80
for header, body in inheaders.iteritems():
81
# Ignore empty headers
85
if header in ('Default-Start', 'Default-Stop'):
43
86
headers[header] = map(int, body.split())
44
elif header in ('Required-Start', 'Required-Stop', 'Provides'):
87
elif header in ('Required-Start', 'Required-Stop', 'Provides',
88
'Should-Start', 'Should-Stop'):
45
89
headers[header] = body.split()
47
91
headers[header] = body
59
items = facilities.items()
60
fh = open(FACILITIES, 'w')
61
for facility, entries in items:
62
if facility[0] == '$': continue
63
for scriptname, pri in entries.items():
103
fh = file(FACILITIES, 'w')
104
for facility, entries in facilities.items():
105
# Ignore system facilities
106
if facility.startswith('$'): continue
107
for (scriptname, pri) in entries.items():
65
109
print >> fh, "%(scriptname)s %(facility)s %(start)d %(stop)d" % locals()
71
115
for line in open(FACILITIES).xreadlines():
73
117
scriptname, name, start, stop = line.strip().split()
74
facilities.get(name, {})[scriptname] = (int(start), int(stop))
118
facilities.setdefault(name, {})[scriptname] = (int(start),
75
120
except ValueError, x:
76
121
print >> sys.stderr, 'Invalid facility line', line
128
if os.path.exists(DEPENDS):
129
independs = RFC822Parser(fileob=file(DEPENDS))
130
for initfile, facilities in independs.iteritems():
131
depends[initfile] = facilities.split()
134
def save_depends(depends):
142
fh = file(DEPENDS, 'w')
143
for initfile, facilities in depends.iteritems():
144
print >> fh, '%s: %s' % (initfile, ' '.join(facilities))
147
if __name__ == '__main__':
148
print scan_initfile('init-fragment')