Operating system for OpenComputers
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

91 lines
2.4KB

  1. local serial = require "serialization"
  2. local rc = {}
  3. rc.pids = {}
  4. local service = {}
  5. local cfg = {}
  6. cfg.enabled = {"getty","minitel"}
  7. local function loadConfig()
  8. local f = io.open("/boot/cfg/rc.cfg","rb")
  9. if not f then return false end
  10. cfg = serial.unserialize(f:read("*a")) or {}
  11. f:close()
  12. cfg.enabled = cfg.enabled or {}
  13. return true
  14. end
  15. local function saveConfig()
  16. local f = io.open("/boot/cfg/rc.cfg","wb")
  17. if not f then return false end
  18. f:write(serial.serialize(cfg))
  19. f:close()
  20. return true
  21. end
  22. function rc.load(name,force) -- string boolean -- table -- Attempts to load service *name*, and if *force* is true, replaces the current instance.
  23. if force then
  24. rc.stop(name)
  25. service[name] = nil
  26. end
  27. if service[name] then return true end
  28. service[name] = setmetatable({},{__index=_G})
  29. local f
  30. f = io.open("/boot/service/"..name..".lua","rb")
  31. if not f then
  32. pcall(require,"pkgfs")
  33. f = io.open("/pkg/service/"..name..".lua","rb")
  34. end
  35. local res = load(f:read("*a"),name,"t",service[name])()
  36. f:close()
  37. return res
  38. end
  39. function rc.stop(name,...) -- string -- boolean string -- Stops service *name*, supplying *...* to the stop function. Returns false and a reason if this fails.
  40. if not service[name] then return false, "service not found" end
  41. if service[name].stop then
  42. service[name].stop(...)
  43. coroutine.yield()
  44. end
  45. if rc.pids[name] then
  46. os.kill(rc.pids[name])
  47. end
  48. rc.pids[name] = nil
  49. end
  50. function rc.start(name,...) -- string -- boolean string -- Stops service *name*, supplying *...* to the stop function. Returns false and a reason if this fails.
  51. rc.load(name)
  52. if not service[name] then return false, "service not found" end
  53. local rv = {service[name].start(...)}
  54. if type(rv[1]) == "number" then
  55. rc.pids[name] = rv[1]
  56. end
  57. end
  58. function rc.restart(name) -- string -- -- Restarts service *name* using rc.stop and rc.start.
  59. rc.stop(name)
  60. rc.start(name)
  61. end
  62. function rc.enable(name) -- string -- -- Enables service *name* being started on startup.
  63. for k,v in pairs(cfg.enabled) do
  64. if v == name then return false end
  65. end
  66. cfg.enabled[#cfg.enabled+1] = name
  67. saveConfig()
  68. end
  69. function rc.disable(name) -- string -- -- Disables service *name* being started on startup.
  70. local disabled = false
  71. for k,v in pairs(cfg.enabled) do
  72. if v == name then table.remove(cfg.enabled,k) disabled = true break end
  73. end
  74. saveConfig()
  75. return disabled
  76. end
  77. loadConfig()
  78. _G.service = service
  79. rc.cfg = cfg
  80. return rc