summaryrefslogtreecommitdiffstats
path: root/spline-startup
blob: 22b325f5f73e2f38952b4393c8647341bcb33957 (plain)
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.1'


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()