File: initdutils.py

package info (click to toggle)
lsb 4.1+Debian8+deb7u1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 500 kB
  • sloc: python: 1,179; sh: 276; makefile: 67; perl: 6
file content (177 lines) | stat: -rw-r--r-- 4,829 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# Support for scanning init scripts for LSB info

import re, sys, os, cStringIO
import cPickle

try:
    assert True
except:
    True = 1
    False = 0

class RFC822Parser(dict):
    "A dictionary-like object."
    __linere = re.compile(r'([^:]+):\s*(.*)$')
    
    def __init__(self, fileob=None, strob=None, startcol=0, basedict=None):
        if not fileob and not strob:
            raise ValueError, 'need a file or string'
        if not basedict:
            basedict = {}
        
        super(RFC822Parser, self).__init__(basedict)

        if not fileob:
            fileob = cStringIO.StringIO(strob)

        key = None
        for line in fileob:
            if startcol:
                line = line[startcol:]

            if not line.strip():
                continue

            # Continuation line
            if line[0].isspace():
                if not key:
                    continue
                self[key] += '\n' + line.strip()
                continue

            m = self.__linere.match(line)
            if not m:
                # Not a valid RFC822 header
                continue
            key, value = m.groups()
            self[key] = value.strip()

# End of RFC882Parser

LSBLIB = '/var/lib/lsb'
FACILITIES = os.path.join(LSBLIB, 'facilities')
DEPENDS = os.path.join(LSBLIB, 'depends')
LSBINSTALL = os.path.join(LSBLIB, 'lsbinstall')

beginre = re.compile(re.escape('### BEGIN INIT INFO'))
endre = re.compile(re.escape('### END INIT INFO'))
#linere = re.compile(r'\#\s+([^:]+):\s*(.*)')

def scan_initfile(initfile):
    headerlines = ''
    scanning = False
    
    for line in file(initfile):
        line = line.rstrip()
        if beginre.match(line):
            scanning = True
            continue
        elif scanning and endre.match(line):
            scanning = False
            continue
        elif not scanning:
            continue

        if line.startswith('# '):
            headerlines += line[2:] + '\n'
        elif line.startswith('#\t'):
            headerlines += line[1:] + '\n'

    inheaders = RFC822Parser(strob=headerlines)
    headers = {}
    for header, body in inheaders.iteritems():
        # Ignore empty headers
        if not body.strip():
            continue
        
        if header in ('Default-Start', 'Default-Stop'):
            headers[header] = map(int, body.split())
        elif header in ('Required-Start', 'Required-Stop', 'Provides',
                        'Should-Start', 'Should-Stop'):
            headers[header] = body.split()
        else:
            headers[header] = body

    return headers

def save_facilities(facilities):
    if not facilities:
        try:
            os.unlink(FACILITIES)
        except OSError:
            pass
        return
    
    fh = file(FACILITIES, 'w')
    for facility, entries in facilities.items():
        # Ignore system facilities
        if facility.startswith('$'): continue
        for (scriptname, pri) in entries.items():
            start, stop = pri
            print >> fh, "%(scriptname)s %(facility)s %(start)d %(stop)d" % locals()
    fh.close()

def load_facilities():
    facilities = {}
    if os.path.exists(FACILITIES):
        for line in open(FACILITIES).xreadlines():
            try:
                scriptname, name, start, stop = line.strip().split()
                facilities.setdefault(name, {})[scriptname] = (int(start),
                                                               int(stop))
            except ValueError, x:
                print >> sys.stderr, 'Invalid facility line', line

    return facilities

def load_depends():
    depends = {}

    if os.path.exists(DEPENDS):
        independs = RFC822Parser(fileob=file(DEPENDS))
        for initfile, facilities in independs.iteritems():
            depends[initfile] = facilities.split()
    return depends

def save_depends(depends):
    if not depends:
        try:
            os.unlink(DEPENDS)
        except OSError:
            pass
        return
    
    fh = file(DEPENDS, 'w')
    for initfile, facilities in depends.iteritems():
        print >> fh, '%s: %s' % (initfile, ' '.join(facilities))
    fh.close()

# filemap entries are mappings, { (package, filename) : instloc }
def load_lsbinstall_info():
    if not os.path.exists(LSBINSTALL):
        return {}
    
    fh = open(LSBINSTALL, 'rb')
    filemap = cPickle.load(fh)
    fh.close()

    # Just in case it's corrupted somehow
    if not isinstance(filemap, dict):
        return {}

    return filemap

def save_lsbinstall_info(filemap):
    if not filemap:
        try:
            os.unlink(LSBINSTALL)
        except OSError:
            pass
        return
    
    fh = open(LSBINSTALL, 'wb')
    cPickle.dump(fh, filemap)
    fh.close()

if __name__ == '__main__':
    print scan_initfile('init-fragment')