1 # Support for scanning init scripts for LSB info
3 import re, sys, os, cStringIO
12 class RFC822Parser(dict):
13 "A dictionary-like object."
14 __linere = re.compile(r'([^:]+):\s*(.*)$')
16 def __init__(self, fileob=None, strob=None, startcol=0, basedict=None):
17 if not fileob and not strob:
18 raise ValueError, 'need a file or string'
22 super(RFC822Parser, self).__init__(basedict)
25 fileob = cStringIO.StringIO(strob)
30 line = line[startcol:]
39 self[key] += '\n' + line.strip()
42 m = self.__linere.match(line)
44 # Not a valid RFC822 header
46 key, value = m.groups()
47 self[key] = value.strip()
51 LSBLIB = '/var/lib/lsb'
52 FACILITIES = os.path.join(LSBLIB, 'facilities')
53 DEPENDS = os.path.join(LSBLIB, 'depends')
54 LSBINSTALL = os.path.join(LSBLIB, 'lsbinstall')
56 beginre = re.compile(re.escape('### BEGIN INIT INFO'))
57 endre = re.compile(re.escape('### END INIT INFO'))
58 #linere = re.compile(r'\#\s+([^:]+):\s*(.*)')
60 def scan_initfile(initfile):
64 for line in file(initfile):
66 if beginre.match(line):
69 elif scanning and endre.match(line):
75 if line.startswith('# '):
76 headerlines += line[2:] + '\n'
77 elif line.startswith('#\t'):
78 headerlines += line[1:] + '\n'
80 inheaders = RFC822Parser(strob=headerlines)
82 for header, body in inheaders.iteritems():
83 # Ignore empty headers
87 if header in ('Default-Start', 'Default-Stop'):
88 headers[header] = map(int, body.split())
89 elif header in ('Required-Start', 'Required-Stop', 'Provides',
90 'Should-Start', 'Should-Stop'):
91 headers[header] = body.split()
93 headers[header] = body
97 def save_facilities(facilities):
100 os.unlink(FACILITIES)
105 fh = file(FACILITIES, 'w')
106 for facility, entries in facilities.items():
107 # Ignore system facilities
108 if facility.startswith('$'): continue
109 for (scriptname, pri) in entries.items():
111 print >> fh, "%(scriptname)s %(facility)s %(start)d %(stop)d" % locals()
114 def load_facilities():
116 if os.path.exists(FACILITIES):
117 for line in open(FACILITIES).xreadlines():
119 scriptname, name, start, stop = line.strip().split()
120 facilities.setdefault(name, {})[scriptname] = (int(start),
122 except ValueError, x:
123 print >> sys.stderr, 'Invalid facility line', line
130 if os.path.exists(DEPENDS):
131 independs = RFC822Parser(fileob=file(DEPENDS))
132 for initfile, facilities in independs.iteritems():
133 depends[initfile] = facilities.split()
136 def save_depends(depends):
144 fh = file(DEPENDS, 'w')
145 for initfile, facilities in depends.iteritems():
146 print >> fh, '%s: %s' % (initfile, ' '.join(facilities))
149 # filemap entries are mappings, { (package, filename) : instloc }
150 def load_lsbinstall_info():
151 if not os.path.exists(LSBINSTALL):
154 fh = open(LSBINSTALL, 'rb')
155 filemap = cPickle.load(fh)
158 # Just in case it's corrupted somehow
159 if not isinstance(filemap, dict):
164 def save_lsbinstall_info(filemap):
167 os.unlink(LSBINSTALL)
172 fh = open(LSBINSTALL, 'wb')
173 cPickle.dump(fh, filemap)
176 if __name__ == '__main__':
177 print scan_initfile('init-fragment')