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
|
#!/usr/bin/env python
from __future__ import print_function
import argparse
import os
import pwd
import sys
import syslog
from subprocess import Popen, PIPE, STDOUT
from pipes import quote
VERSION = '1.0'
def is_root():
return os.getuid() == 0
class SplineStartup(object):
def __init__(self):
self.options = None
self._parse_args()
if self.options.syslog:
syslog.openlog(logoption=syslog.LOG_PID)
def _parse_args(self):
parser = argparse.ArgumentParser(description='Startup for users.')
parser.add_argument('action', metavar='ACTION', nargs='?',
default='start',
help='argument supplied to each called '
'script (default: %(default)s)')
parser.add_argument('-q', '--quiet', action='store_true',
help='only log error messages')
parser.add_argument('-v', '--verbose', action='store_true',
help='print extra debugging mesasges to stderr')
parser.add_argument('-V', '--version', action='version',
version='%(prog)s ' + VERSION)
parser.add_argument('-n', '--dry-run', action='store_true',
help="print script names which would run, "
"but don't run them")
parser.add_argument('-s', '--syslog', action='store_true',
help='log to syslog and not to stderr')
if is_root():
parser.add_argument('-u', '--user', metavar='USER',
action='append',
help='user to execute scripts (by default all '
'users with 1000 <= uid < 2000 are used)')
self.options = parser.parse_args()
def _perror(self, msg):
if self.options.syslog:
syslog.syslog(syslog.LOG_CRIT, msg)
else:
print('[ERROR] %s' % msg, file=sys.stderr)
def _pinfo(self, msg):
if self.options.syslog:
syslog.syslog(syslog.LOG_INFO, msg)
elif not self.options.quiet:
print('[INFO] %s' % msg, file=sys.stderr)
def _pdebug(self, msg):
if self.options.syslog:
syslog.syslog(syslog.LOG_DEBUG, msg)
elif self.options.verbose:
print('[DEBUG] %s' % msg, file=sys.stderr)
def _call(self, cmd):
self._pinfo('Calling: %s' % ' '.join(cmd))
if not self.options.dry_run:
proc = Popen(cmd, stdout=PIPE, stderr=STDOUT)
output, _ = proc.communicate()
output = output.strip()
if output != '':
for line in output.split('\n'):
self._pinfo(line)
return proc.wait()
else:
return 0
def _run_scripts(self, user, action, su=True):
self._pdebug("Running scripts for user '%s'" % user.pw_name)
dir = os.path.join(user.pw_dir, 'etc', 'rc.d')
args = ['--arg=%s' % quote(action)]
if action == 'stop':
args.append('--reverse')
if not os.path.isdir(dir):
return True
if su:
returnvalue = self._call(['su', '-', user.pw_name,
'-c', 'run-parts %s -- %s' %
(' '.join(args), quote(dir))])
else:
returnvalue = self._call(['run-parts'] + args + ['--', dir])
return returnvalue == 0
def run(self):
if not is_root():
user = pwd.getpwuid(os.getuid())
self._run_scripts(user, self.options.action, False)
return
if self.options.user is not None:
for username in self.options.user:
try:
user = pwd.getpwnam(username)
self._run_scripts(user, self.options.action)
except KeyError:
self._perror("Invalid user '%s'" % user)
else:
for user in pwd.getpwall():
if user.pw_uid < 1000 or user.pw_uid >= 2000:
continue
self._run_scripts(user, self.options.action)
if __name__ == '__main__':
app = SplineStartup()
app.run()
|