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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
module(..., package.seeall)
-- Load libraries
require("modelfunctions")
require("posix")
require("fs")
require("format")
require("validator")
-- Set variables
local processname = "postfix"
local packagename = "postfix"
local baseurl = "/etc/postfix/"
local aliasesfile = "/etc/mail/aliases"
local path = "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin "
-- ################################################################################
-- LOCAL FUNCTIONS
-- ################################################################################
-- PUBLIC FUNCTIONS
function startstop_service(action)
return modelfunctions.startstop_service(processname, action, {"start", "stop", "restart", "reload"})
end
function getstatus()
local status = modelfunctions.getstatus(processname, packagename, "Postfix Status")
-- Enabled status is unique for postfix
-- Look for pid file stored in queue_directory .. /pid/
local config = format.parse_ini_file(fs.read_file(baseurl.."main.cf") or "", "") or {}
if config.queue_directory then
local pidfiles = fs.find_files_as_array(".*\.pid", config.queue_directory.."/pid/")
if pidfiles and pidfiles[1] then
local file = pidfiles[1]
-- check to see if there's a matching proc directory and that it was created slightly after the pid file
-- this allows us to avoid the problem with proc numbers wrapping
local tmp = string.match(fs.read_file(file) or "", "%d+")
if tmp then
local dir = "/proc/" .. tmp
filetime = posix.stat(file, "ctime")
dirtime = posix.stat(dir, "ctime")
if dirtime and (tonumber(dirtime) - tonumber(filetime) < 100) then
status.value.status.value = "Running"
end
end
end
end
return status
end
function getstatusdetails()
return cfe({ type="longtext", value="", label="Postfix Status Details" })
end
local function geteditablefilelist()
local listed_files = fs.find_files_as_array("[^%.].*", baseurl)
table.insert(listed_files, aliasesfile)
return listed_files
end
function getfilelist()
local listed_files = {}
for i,name in ipairs(geteditablefilelist()) do
local filedetails = fs.stat(name) or {}
table.insert ( listed_files , {filename=name, mtime=filedetails.mtime or "---", filesize=filedetails.size or "0"} )
end
table.sort(listed_files, function (a,b) return (a.filename < b.filename) end )
return cfe({ type="list", value=listed_files, label="Postfix File List" })
end
function getfiledetails(filename)
return modelfunctions.getfiledetails(filename, geteditablefilelist())
end
function updatefiledetails(filedetails)
return modelfunctions.setfiledetails(filedetails, geteditablefilelist())
end
function getnewfile()
local options = {}
options.filename = cfe({ label="File Name" })
return cfe({ type="group", value=options, label="New File" })
end
function createfile(newfile)
newfile.errtxt = "Failed to create file"
local path = newfile.value.filename.value
if not string.find(path, "/") then
path = baseurl..path
end
if validator.is_valid_filename(path, baseurl) then
if posix.stat(path) then
newfile.value.filename.errtxt = "File already exists"
else
fs.create_file(path)
newfile.errtxt = nil
end
else
newfile.value.filename.errtxt = "Invalid filename"
end
return newfile
end
function deletefile(filename)
local result = cfe({ value="Failed to delete file", label="Delete file result" })
if not validator.is_valid_filename(filename, baseurl) then
result.errtxt = "Not a valid filename!"
elseif not fs.is_file(filename) then
result.errtxt = "File doesn't exist!"
else
os.remove(filename)
result.value = "File Deleted"
end
return result
end
function rebuild_databases()
local result = cfe({ value={"Rebuilding databases"}, label="Rebuild Databases result" })
table.insert(result.value, " See logfile for possible errors")
local cmd,f,cmdresult
-- parse main.cf looking for hash files
local config = format.parse_ini_file(fs.read_file("/etc/postfix/main.cf") or "", "") or {}
for name,val in pairs(config) do
-- run postmap on files
local filename = string.match(val, "hash:(.*)")
if filename and not string.find(filename, aliasesfile) then
cmd = "postmap "..filename
table.insert(result.value, "Running: "..cmd)
f = io.popen(format.escapespecialcharacters(path..cmd))
table.insert(result.value, f:read("*a"))
f:close()
end
end
-- finally, run newaliases
cmd = "newaliases"
table.insert(result.value, "Running: "..cmd)
f = io.popen(format.escapespecialcharacters(path..cmd))
table.insert(result.value, f:read("*a"))
f:close()
result.value = table.concat(result.value, "\n")
return result
end
|