2020-03-20 13:15:02 +11:00
local serial = require " serialization "
local rc = { }
2020-06-29 15:31:32 +10:00
rc.paths = " /boot/service \n /pkg/service "
2020-03-24 16:27:51 +11:00
rc.pids = { }
2020-03-20 13:15:02 +11:00
local service = { }
local cfg = { }
2020-03-26 17:32:54 +11:00
cfg.enabled = { " getty " , " minitel " }
2020-03-20 13:15:02 +11:00
local function loadConfig ( )
local f = io.open ( " /boot/cfg/rc.cfg " , " rb " )
if not f then return false end
cfg = serial.unserialize ( f : read ( " *a " ) ) or { }
f : close ( )
cfg.enabled = cfg.enabled or { }
return true
end
local function saveConfig ( )
local f = io.open ( " /boot/cfg/rc.cfg " , " wb " )
if not f then return false end
f : write ( serial.serialize ( cfg ) )
f : close ( )
return true
end
2020-06-29 15:31:32 +10:00
function rc . load ( name , force ) -- string boolean -- table -- Attempts to load service *name*, and if *force* is true, replaces the current instance.
if not package.loaded [ name ] or force then
for d in rc.paths : gmatch ( " [^ \n ]+ " ) do
if fs.exists ( d .. " / " .. name .. " .lua " ) then
service [ name ] = runfile ( d .. " / " .. name .. " .lua " )
end
end
end
if service [ name ] then
return service [ name ]
end
return false , " unable to load service " .. name
end
--[[
2020-05-12 10:57:13 +10:00
function rc . load ( name , force ) -- string boolean -- table -- Attempts to load service *name*, and if *force* is true, replaces the current instance.
2020-03-20 13:15:02 +11:00
if force then
rc.stop ( name )
service [ name ] = nil
end
if service [ name ] then return true end
service [ name ] = setmetatable ( { } , { __index = _G } )
2020-06-07 23:35:24 +10:00
local f
f = io.open ( " /boot/service/ " .. name .. " .lua " , " rb " )
if not f then
pcall ( require , " pkgfs " )
f = io.open ( " /pkg/service/ " .. name .. " .lua " , " rb " )
end
2020-03-20 13:15:02 +11:00
local res = load ( f : read ( " *a " ) , name , " t " , service [ name ] ) ( )
f : close ( )
return res
end
2020-06-29 15:31:32 +10:00
] ]
2020-03-20 13:15:02 +11:00
2020-05-12 10:57:13 +10:00
function rc . stop ( name , ... ) -- string -- boolean string -- Stops service *name*, supplying *...* to the stop function. Returns false and a reason if this fails.
2020-03-20 13:15:02 +11:00
if not service [ name ] then return false , " service not found " end
2020-03-26 17:32:54 +11:00
if service [ name ] . stop then
service [ name ] . stop ( ... )
coroutine.yield ( )
end
2020-03-24 16:27:51 +11:00
if rc.pids [ name ] then
os.kill ( rc.pids [ name ] )
end
rc.pids [ name ] = nil
2020-03-20 13:15:02 +11:00
end
2020-05-12 10:57:13 +10:00
function rc . start ( name , ... ) -- string -- boolean string -- Stops service *name*, supplying *...* to the stop function. Returns false and a reason if this fails.
2020-03-20 13:15:02 +11:00
rc.load ( name )
if not service [ name ] then return false , " service not found " end
2020-03-24 16:27:51 +11:00
local rv = { service [ name ] . start ( ... ) }
if type ( rv [ 1 ] ) == " number " then
rc.pids [ name ] = rv [ 1 ]
end
2020-03-20 13:15:02 +11:00
end
2020-05-12 10:57:13 +10:00
function rc . restart ( name ) -- string -- -- Restarts service *name* using rc.stop and rc.start.
2020-03-20 13:15:02 +11:00
rc.stop ( name )
rc.start ( name )
end
2020-05-12 10:57:13 +10:00
function rc . enable ( name ) -- string -- -- Enables service *name* being started on startup.
2020-03-20 13:15:02 +11:00
for k , v in pairs ( cfg.enabled ) do
if v == name then return false end
end
2020-03-26 17:32:54 +11:00
cfg.enabled [ # cfg.enabled + 1 ] = name
2020-03-20 13:15:02 +11:00
saveConfig ( )
end
2020-05-12 10:57:13 +10:00
function rc . disable ( name ) -- string -- -- Disables service *name* being started on startup.
2020-03-20 13:15:02 +11:00
local disabled = false
for k , v in pairs ( cfg.enabled ) do
if v == name then table.remove ( cfg.enabled , k ) disabled = true break end
end
saveConfig ( )
return disabled
end
loadConfig ( )
_G.service = service
2020-03-20 13:15:54 +11:00
rc.cfg = cfg
2020-03-20 13:15:02 +11:00
return rc