module(..., package.seeall) require("fs") require("procps") require("getopts") require("format") require("daemoncontrol") require("validator") local configfile = "/etc/conf.d/syslog" local config = {} local function get_version() local cmd = "/sbin/apk_version -v -s busybox | cut -d ' ' -f 1" local cmd_output = io.popen( cmd ) local cmd_output_result = cmd_output:read("*a") or "" cmd_output:close() return cmd_output_result end local function getloglevels() local loglevels = {} for i=1,8 do table.insert(loglevels,i) end return loglevels end -- ################################################################################ -- PUBLIC FUNCTIONS function startstop_service ( self, state ) return daemoncontrol.daemoncontrol("syslog", state) end function getstatus() local opts = getconfig() local status = {} status.version = cfe({ name = "version", label="Program version", value=get_version(), }) status.status = cfe({ name="status", label="Program status", value=procps.pidof("syslogd"), }) if (opts["remotelogging"]) and not ((opts["remotelogging"]["value"] ~= "") and not (opts["localandnetworklog"]["value"])) then status.logfile = cfe({ name="logfile", label="Locally logging to", value=opts["logfile"]["value"], }) end if (opts["SYSLOGD_OPTS"]) and (opts["SYSLOGD_OPTS"]["-R"]) and (opts["SYSLOGD_OPTS"]["-R"] ~= "") then status.remote = cfe({ name="remotelogging", label="Remote logging to", value=opts["SYSLOGD_OPTS"]["-R"], }) end return status end function get_filedetails() local filedetails = {} local path = configfile filedetails.details = {path=path, size="0",mtime=""} filedetails.content = "" if (fs.is_file(path)) then filedetails.details = fs.stat(path) filedetails.content = fs.read_file(path) end return filedetails end function getconfig() local config = {} if (fs.is_file(configfile)) then configcontent = getopts.getoptsfromfile(configfile) or config if (type(config["SYSLOGD_OPTS"]) == "string") then config["SYSLOGD_OPTS"] = {} end else config["configfile"] = "Config file '".. configfile .. "' is missing!" end -- Next section selects which configurations we should show to the user config["logfile"] = cfe({ name="logfile", label = "Log to given file", value = configcontent["SYSLOGD_OPTS"]["-O"] or "/var/log/messages", }) config["loglevel"] = cfe({ name="loglevel", label = "Set local log level", value = tonumber(configcontent["SYSLOGD_OPTS"]["-l"]) or 8, type = "select", option = getloglevels(), descr = "1=Quiet, ... , " .. table.maxn(getloglevels()) .. "=Debug", }) config["smallerlogs"] = cfe({ name="smallerlogs", label = "Smaller logging output", checked = configcontent["SYSLOGD_OPTS"]["-S"], value = "smallerlogs", type = "checkbox", }) config["maxsize"] = cfe ({ name="maxsize", label = "Max size (KB) before rotate", descr = "Default=200KB, 0=off", value = configcontent["SYSLOGD_OPTS"]["-s"], }) config["numrotate"] = cfe ({ name="numrotate", label = "Number of rotated logs to keep", descr = "Default=1, max=99, 0=purge", value = configcontent["SYSLOGD_OPTS"]["-b"], }) config["localandnetworklog"] = cfe ({ name="localandnetworklog", label = "Log locally and via network", checked = configcontent["SYSLOGD_OPTS"]["-L"], value = "localandnetworklog", type = "checkbox", descr = "Default is network only if -R", }) config["remotelogging"] = cfe ({ name="remotelogging", label = "Log to IP or hostname on PORT", descr = "host[:PORT] - Default PORT=514/UDP", value = configcontent["SYSLOGD_OPTS"]["-R"], }) -- Next section is to print errormessages when configs are wrong if (configcontent["SYSLOGD_OPTS"]["-l"]) and ((tonumber(configcontent["SYSLOGD_OPTS"]["-l"]) == nil) or (tonumber(configcontent["SYSLOGD_OPTS"]["-l"]) > 8)) then config["loglevel"]["errtxt"] = "Log value is out of range. Please select one of the above." end if (configcontent["SYSLOGD_OPTS"]["-L"] ~= nil) and (configcontent["SYSLOGD_OPTS"]["-R"] == "") then config["localandnetworklog"]["errtxt"] = "Logging to local and network is possible unless you define a host for remote logging." end return config end service_control = function ( self, srvcmd ) local srvcmd = string.lower(srvcmd) local retval = "" local line = "" if (srvcmd == "start") or (srvcmd == "stop") or (srvcmd == "restart") then local file = io.popen( "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin /etc/init.d/syslog " .. srvcmd .. " 2>&1" ) if file ~= nil then line = file:read( "*l" ) while line ~= nil do retval = retval .. "\n" .. line line = file:read( "*l" ) end file:close() end else retval = "Unknown command!" end return retval end function setconfigs(self,variable,parameter,value) local variabletranslator = ({ logfile = "-O", loglevel = "-l", smallerlogs = "-S", maxsize = "-s", numrotate = "-b", localandnetworklog = "-L", remotelogging = "-R", }) parameter = variabletranslator[parameter] --TODO: Validate so that user cant add values with '-' (could cause major breakage next time you do getopts) --If file is missing... then create a new one -- if not (fs.is_file(configfile)) then fs.write_file(configfile, "SYSLOGD_OPTS=\"\"\nKLOGD_OPTS=\"\"") end if not (variable) or not (parameter) then return nil, "Usage setconfigs(variable,parameter,value)" end if not (string.find(parameter, "-%a$")) then return nil, "Parameter must be formated '-a' (where a is one upper/lowercase letter [a-z])" end if (value) and (parameter == "-O") then local value, errors = validator.is_valid_filename(value, "/var/log" ) if (errors) then return cfe({ name="setconfig", errtxt= errors, }) end end --[[ if (value) and (parameter == "-R") then local port = string.match(value, ":(.-)$") local host = string.match(value, "^(.-):?") if (port) and not (validator.is_port(port)) then errors["-R"] = "Port:'" .. tostring(port) .. "' is not a valid portnumber!" end errors["-R"] = "Port:'" .. tostring(port) .. "' Host:" .. tostring(host) end --]] -- Set specific variables (and their values) if (value) and ((parameter == "-S") or (parameter == "-L")) then value = "" end local retval, errorscmd = getopts.setoptsinfile(configfile,variable,parameter,value) -- if (errorscmd) and (#errorscmd > 0) then local errorscmd = cfe({ name="variable", errtxt=errorscmd, }) -- end return errorscmd end function update_filecontent (self, modifications) local path = configfile local file_result,err = fs.write_file(path, format.dostounix(modifications)) return file_result, err end -- ################################################################################ -- OTHER FUNCTIONS