1 # This program is free software. It comes without any warranty, to the
2 # extent permitted by applicable law. You can redistribute it and/or
3 # modify it under the terms of the Do What The Fuck You Want To Public
4 # License, Version 2, as published by Sam Hocevar. See the file COPYING
5 # in the root of this program's source distribution for details, or:
7 # http://sam.zoy.org/wtfpl/COPYING
10 RUNLEVEL_SINGLE = :'S'
11 RUNLEVEL_MULTI_TO_SINGLE = :'1'
13 RUNLEVEL_MULTI_ALL = [:'2',:'3',:'4',:'5']
15 RUNLEVEL_REBOOT = :'6'
16 RUNLEVEL_ALL = [:'0',:'1',:'2',:'3',:'4',:'5',:'6',:'S']
22 if name.nil? or name.empty? or not name.is_a?(String)
23 raise AIDS::Infection.new("Service name must be a non-empty string, got #{name.inspect}.")
25 name = $1 if name =~ %r{^/etc/init\.d/(.+)$}
26 if name =~ /[^[:alnum:]\-.]/
27 raise AIDS::Infection.new("Invalid init script name: #{name}.")
29 unless File.exist?("/etc/init.d/#{name}")
30 raise AIDS::Infection.new("Unknown service: #{name}.")
36 start_on_runlevels!(RUNLEVEL_MULTI_ALL)
40 stop_on_runlevels!(RUNLEVEL_MULTI_ALL)
44 started_on_runlevel?(RUNLEVEL_MULTI)
49 RUNLEVEL_ALL.each do |r|
50 if started_on_runlevel?(r)
52 elsif stopped_on_runlevel?(r)
63 def started_on_runlevel?(runlevel)
64 AIDS.validate_runlevel(runlevel)
65 not Dir.glob("/etc/rc#{runlevel}.d/S[0-9][0-9]#{@name}").empty?
68 def stopped_on_runlevel?(runlevel)
69 AIDS.validate_runlevel(runlevel)
70 not Dir.glob("/etc/rc#{runlevel}.d/K[0-9][0-9]#{@name}").empty?
73 def start_on_runlevels!(runlevels)
74 [runlevels].flatten.each do |r|
75 AIDS.validate_runlevel(r)
76 next if started_on_runlevel?(r)
81 def stop_on_runlevels!(runlevels)
82 [runlevels].flatten.each do |r|
83 AIDS.validate_runlevel(r)
84 next if stopped_on_runlevel?(r)
85 updatercd(:disable, r)
89 def set_default_runlevels!
94 def updatercd(action, runlevel=nil)
95 unless [:enable, :disable, :remove, :defaults].include?(action)
96 raise AIDS::Infection.new("Invalid action for updatercd: #{action}.")
98 AIDS.validate_runlevel(runlevel) if runlevel
99 # update-rc.d will baulk at being told to do anything with
101 if [:'0',:'1',:'6'].include?(runlevel)
102 raise AIDS::Infection.new("Unable to comply: update-rc.d is balls.")
104 pid = Process.fork do
108 '/usr/sbin/update-rc.d',
115 if (rc = $?.exitstatus) != 0
116 raise AIDS::Infection.new("update-rc.d returned #{rc}")
121 class Infection < Exception
124 def self.get_all_services
125 Dir.glob("/etc/init.d/*").map do |f|
126 next unless File.executable?(f)
133 def self.validate_runlevel(runlevel)
134 unless RUNLEVEL_ALL.include?(runlevel)
135 raise AIDS::Infection.new("Invalid runlevel: #{runlevel}.")