2 -- return output & return value
4 cmd
= cmd
..[[ 2>&1; echo -e "\nKylin_RETURN$?"]]
5 local _pfile
= assert(io
.popen(cmd
))
6 local _s
= _pfile
:read("*all")
8 _
,_
,_s
, _r
= string.find(_s
, "(.*)\nKylin_RETURN(%d+)")
9 return _s
, tonumber(_r
)
12 ----------------------------------------------
14 local _f
= assert(io
.open(file
, "r"))
15 local _t
= _f
:read("*all")
20 function mywrite(file
, s
)
21 local _tn
= os
.tmpname()
22 local _tf
= assert(io
.open(_tn
, "w"))
25 assert(0 == os
.execute("sudo /bin/cp ".._tn
.." "..file
), "[Error] - ".."cp ".._tn
.." "..file
)
26 return os
.execute("rm ".._tn
)
29 function read_file_lines(filename
)
30 local t
= myread(filename
)
32 string.gsub(t
, "(.-[\n$])", function(l
) table.insert(lines
,l
) end)
36 function flush_file_lines(filename
, lines
)
37 mywrite(filename
, table.concat(lines
))
41 if (v
== 1) then return 2 end
45 function sec2string(t
)
46 sec
= assert(tonumber(t
))
49 elseif (sec
< 60*60 ) then
50 return string.format("%d分%d秒", sec
/60, sec
%60)
51 elseif (sec
< 86400) then
52 return string.format("%d小时%d分%d秒", sec
/(3600), (sec
%3600)/60,sec
%3600%60)
54 return string.format("%d天%d小时%d分%d秒",sec
/(86400), (sec
%86400)/(3600),
55 (sec
%86400%3600)/60, sec
%86400%3600%60)
60 return string.format("%02d:%02d:%02d/%4d年%02d月%02d日",
61 t
["hour"],t
["min"],t
["sec"],t
["year"],t
["month"],t
["day"])
64 function size2hum(size
)
65 s
= assert(tonumber(string.sub(size
, 1, -2)), "size2hum: Not number")
66 u
= string.lower(string.sub(size
, -1, -1))
67 assert(u
== "b" or u
== "k" or u
== "m", [[size2hum: Unit not 'b' or 'k' or 'm']])
70 if (s
< 1024 ) then return s
.."Byte"
71 elseif (s
< 1048576 ) then return string.format("%.2f", s
/1024).." Kb"
72 elseif (s
< 1073741824 ) then return string.format("%.2f", s
/1024/1024).." MB"
73 elseif (s
< 1073741824*1024) then return string.format("%.2f", s
/1024/1024/1024).." GB"
74 else return string.format("%.2f", s
/1024/1024/1024/1024).."TB"
77 if (s
< 1024 ) then return s
.." Kb"
78 elseif (s
< 1048576 ) then return string.format("%.2f", s
/1024).." Mb"
79 elseif (s
< 1073741824 ) then return string.format("%.2f", s
/1024/1024).." GB"
80 else return string.format("%.2f", s
/1024/1024/1024).." TB"
83 if (s
< 1024 ) then return s
.." Mb"
84 elseif (s
< 1048576 ) then return string.format("%.2f", s
/1024).." Gb"
85 else return string.format("%.2f", s
/1024/1024).." TB"
90 -- do string.gsub on a file instead of on a string
91 function file_gsub(file
, s
, g
)
92 local _f
= assert(io
.open(file
, "r"))
93 local _t
= _f
:read("*all")
94 _t
= string.gsub(_t
, s
, g
)
97 local _tn
= os
.tmpname()
98 local _tf
= assert(io
.open(_tn
, "w"))
102 assert(0 == os
.execute("sudo /bin/cp ".._tn
.." "..file
), "[Error] - ".."cp ".._tn
.." "..file
)
103 os
.execute("rm ".._tn
)
106 -----------------------------------------------------------------------------
107 -- check with the email string is valid
109 --@param email the email string
110 --@return the email string or false
111 -----------------------------------------------------------------------------
112 function is_email_valid(email
)
113 return string.match(email
,"^[%a][%w%.%-]*[%a%d]*@[%a%d][%w%.%-]*[%a%d]%.[%a][%a]?[%a]?[%a]$")
115 -----------------------------------------------------------------------------
117 -----------------------------------------------------------------------------
120 function message_err(s
)
121 print([[<div class="messageblock messageblock-error">
122 <div class="messageblock-internal">
123 <p><ul><strong>出现了下面的错误</strong><li>]]..s
..[[
128 function ui_message_err(s
)
129 print([[<div class="messageblock messageblock-error">
130 <div class="messageblock-internal">
131 <p><ul><strong>出现了下面的错误</strong><li>]]..s
..[[
136 function ui_message_warning(s
)
137 print([[<div class="messageblock messageblock-warning">
138 <div class="messageblock-internal">
144 function ui_message_info(s
)
145 print([[<div class="messageblock messageblock-info">
146 <div class="messageblock-internal">
151 function ui_message_success(s
)
152 local success
= " ... <font color=green><strong>成功</strong></font><br>"
156 function ui_redblue_img(red
, blue
)
157 wred
= red
*300/(red
+blue
)
158 wred
= string.format("%d", wred
)
160 return "<img src=images/red.gif width="..wred
.." height=10><img src=images/blue.gif width="..wblue
.." height=10>"
161 -- return [[<img width="1" hspace="0" height="8" border="0" alt="disk usage" src="images/backgrounds/bar-start.gif"/><img width="]] ..wred.. [[" hspace="0" height="8" border="0" alt="disk usage" src="images/backgrounds/bar-active-2-2.gif"/><img width="8" hspace="0" height="]] ..wblue.. [[" border="0" alt="disk usage" src="images/backgrounds/bar-inactive.gif"/><img width="1" hspace="0" height="8" border="0" alt="score" src="images/backgrounds/bar-stop.gif"/>]]
164 function ui_myexec(cmd
)
167 if _r
~= 0 then ui_message_err(_s
) return nil end
173 local _t
= myexec("set")
174 string.gsub(_t
, "(.-)=(.-)\n", function(n
,v
)
176 if(string.sub(n
,1,2) == "F_") then _tbl
[string.sub(n
,3,-1)] = v
end
181 -----------------------------------------------------------------------------
185 -----------------------------------------------------------------------------
187 -----------------------------------------------------------------------------
188 -- LVM and Raid utility
189 -----------------------------------------------------------------------------
191 -- return a table {["vgname"]}.{["size"], ["pvs"]}
195 local fstr
= myexec("sudo /sbin/vgdisplay")
196 for str
in string.gmatch(fstr
, "(---%s*Volume group.-\n)%s*\n") do
197 string.gsub(str
, "VG%s*Name%s*(%S+).-VG%s*Size%s*(.-)\n.-Total%s+PE%s+(%d+)\n", function(v
, s
, pe
)
198 lvm
[v
] = {["size"] = s
, ["pvs"] = "", ["totalpe"] = pe
}
201 fstr
= myexec("sudo /sbin/pvdisplay")
202 string.gsub(fstr
, "PV%s+Name%s+(%S+)\n.-VG%s+Name%s+(%S+)\n", function(p
,v
)
203 lvm
[v
]["pvs"] = lvm
[v
].pvs
.." "..p
210 function is_vg_exist(vgname
)
212 for k
,v
in pairs(vg
) do
213 if k
==vgname
then return true end
219 t
= myexec("/bin/df /mnt")
221 string.gsub(t
, "(%S+)%s*(%S+)%s*(%S+)%s*(%S+)%s*(%S+)%s*/mnt", function(p
,t
,u
,a
,c
)
228 if lvtbl
then return lvtbl
else return nil end
231 function display_lv()
233 if not lv
then print("something wrong: no logic volume") return end
236 <div class="sysinfo">
238 <tr class="boxheader">
239 <td class="boxheader">共享信息</td>
243 <table border="0" width="100%" align="center">
245 print([[<tr valign="top"><td><strong>共享卷使用</strong></td><td>]]
246 ..ui_redblue_img(lv
.used
,lv
.free
)..
247 "( 已使用"..size2hum(lv
.used
..'k').." / 共"..size2hum(lv
.total
..'k')..")<strong> 空闲 "..size2hum(lv
.free
..'k').."</strong></td></tr>")
248 print("</table></td></tr></table>")
251 -- return table {["md"]}.{"active", "level", "devices", "size", "err"}
252 function get_mdstat()
253 local fstr
= myexec("cat /proc/mdstat")
255 for str
in string.gmatch(fstr
, "(md%d%s*:.-\n)%s*\n") do
257 string.gsub(str
, "(md%d+)%s*:%s*(%S+)%s*(%S+)%s*(.-)\n%s*(%d+)%s*blocks%s*(.-)\n", function(m
,a
,l
,d
,s
,e
)
258 mdstat
["/dev/"..m
] = {["active"]=a
,
264 string.gsub(str
,"(md%d+)%s*:.-resync%s*=%s*([0-9%.]+).*$", function(m
, y
)
265 mdstat
["/dev/"..m
]["resync"] = y
270 for k
,v
in pairs(mdstat
) do
271 mdstat
[k
]["size"] = size2hum(mdstat
[k
]["size"].."k")
272 mdstat
[k
]["devices"] = string.gsub(mdstat
[k
]["devices"], "(%S+)%[.-%]", "/dev/%1")
277 -- return table: {["device"] = ["filesystem"]}
279 local fstr
= myexec("cat /etc/mtab")
281 string.gsub(fstr
, "(/dev/%S+)%s+(/%S*)", function(d
,f
)
287 -- return table {["device"] }. {["size"],["vendor"],["model"]}
288 function _get_physical_disks()
289 local fstr
= myexec("sudo /sbin/fdisk -l")
292 string.gsub(fstr
, "Disk%s+(/dev/%S+):%s+(.-),", function(d
, s
)
293 disktbl
[d
] = {["size"] = s
}
294 local istr
= myexec("sudo /usr/bin/sginfo "..d
)
295 string.gsub(istr
, "Vendor:%s*(%S.-)\nProduct:%s+(%S.-)\n", function(v
,p
)
296 disktbl
[d
]["vendor"] = v
297 disktbl
[d
]["model"] = p
304 -- return table {["device"] }. {["size"],["vendor"],["model"], ["used"]}
305 function _get_block_devices(mtab
, vg
, raid
, ttype
)
306 local disks
= _get_physical_disks()
307 for d
in pairs(mtab
) do
308 local d1
=string.match(d
, "(%S+)%d")
310 for d2
in pairs(disks
) do
311 if d1
== d2
then disks
[d1
]["used"] = "fs" end
315 for m
in pairs(raid
) do
316 for d1
in string.gmatch(raid
[m
].devices
, "(%S+)%d") do
318 for d2
in pairs(disks
) do
319 if d1
== d2
then disks
[d1
]["used"] = "raid" end
325 for v
in pairs(vg
) do
326 for d1
in string.gmatch(vg
[v
].pvs
, "(%S+)%d") do
328 for d2
in pairs(disks
) do
329 if d1
== d2
then disks
[d1
]["used"] = "lvm" end
336 for m
in pairs(raid
) do
338 ["size"] = raid
[m
].size
,
339 ["devices"] = raid
[m
].devices
,
340 ["model"] = raid
[m
].level
342 for v
in pairs(vg
) do
343 for d1
in string.gmatch(vg
[v
].pvs
, "(%S+%d+)") do
344 if d1
== m
then disks
[m
]["used"] = "lvm" end
352 -- return physical disks table {["device"] }. {["size"],["vendor"],["model"], ["used"]}
354 local mtab
= get_mtab()
356 local raid
= get_mdstat()
357 return _get_block_devices(mtab
, vg
, raid
, "d")
361 -- return block device table {["device"] }. {["size"],["vendor"],["model"], ["used"]}
362 function get_block_devices()
363 local mtab
= get_mtab()
365 local raid
= get_mdstat()
366 return _get_block_devices(mtab
, vg
, raid
, "b")
369 -- parted a disk to 2 partitions: 1.swap and 2.xfs, then mount swap,write to fstab
370 function do_disk(disk
)
371 local success
= "<font color=green><strong>成功</strong></font><br>"
372 local fstr
= myexec("sudo /usr/sbin/parted "..disk
.." p")
373 local disksize
= string.match(fstr
, "\nDisk%s+"..disk
..":%s+(%S+)\n")
374 print("<br>disksize: "..disksize
)
375 if not disksize
then ui_message_err("Not get disk size") return end
377 ["label"] = "sudo /usr/sbin/parted -s "..disk
.." mklabel msdos",
378 ["swap"] = "sudo /usr/sbin/parted -s "..disk
.." mkpart primary linux-swap 0 512",
379 ["xfs"] = "sudo /usr/sbin/parted -s "..disk
.." mkpart primary xfs 512 "..disksize
382 local conf
= disk
.."1\tswap\tswap\tdefaults\t0\t0\n"
384 print("<br>正在为磁盘 "..disk
.."分区")
385 myexec("sudo /sbin/swapoff "..disk
.."1")
386 err
, ret
= myexec(cmd
.label
)
387 if ret
~= 0 then ui_message_err(err
) return nil end
388 err
, ret
= myexec(cmd
.swap
)
389 if ret
~= 0 then ui_message_err(err
) return nil end
390 err
, ret
= myexec(cmd
.xfs
)
391 if ret
~= 0 then ui_message_err(err
) return nil else print(success
) end
393 file_gsub("/etc/fstab", "\n"..disk
.."1.-\n", "\n")
394 err
, ret
= mywrite("/etc/fstab", myread("/etc/fstab")..conf
)
395 myexec("sudo /sbin/mkswap "..disk
.."1 && sudo /sbin/swapon "..disk
.."1")
400 -- @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
401 -- ############## SAMBA Utilities #################
402 -- @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
404 smbshare
.config
= "/etc/samba/smb.conf"
405 smbshare
.version
= "# Generated by smbshare util.\n# Author: kang, 2008-09-26\n# e-mail: kkmm99@gmail.com\n"
407 -- return a table from smb.conf: {share,} = {name = value,}
408 function smbshare
.get()
409 local t
= myread(smbshare
.config
)
410 t
= string.gsub(t
, "\n%s*#[^\n]+", "\n")
411 t
= string.gsub(t
, "\n%s*;[^\n]+", "\n")
412 t
= string.gsub(t
, "\n+", "\n") --remove multi lines to one line
413 t
= string.gsub(t
, "%[", "\n%[") -- make an tag "\n\n" at every end of a share
414 t
= string.gsub(t
, "$", "\n\n"); -- make sure there is a tag at end of file
417 string.gsub(t
, "%[(.-)%]%s*\n(.-\n)\n", function(sh
, p
)
419 string.gsub(p
, "%s*(.-)%s*=%s*(.-)%s*\n", function(n
,v
)
426 -- write the table to smb.conf
427 function smbshare
.put(tb
)
428 smbconf
= smbshare
.version
.."[global]\n"
429 for n
, v
in pairs(tb
.global
) do
430 smbconf
= smbconf
.."\t"..n
.." = "..v
.."\n"
433 for s
,k
in pairs(tb
) do
434 if s
~= "global" then
435 smbconf
= smbconf
.."["..s
.."]\n"
436 for n
, v
in pairs(tb
[s
]) do
437 smbconf
= smbconf
.."\t"..n
.." = "..v
.."\n"
441 mywrite(smbshare
.config
, smbconf
)
444 -- return a template share table
445 function smbshare
.new()
446 return {["path"] = "/tmp",
447 ["comment"] = "no comment",
449 ["create mask"] = 666,
450 ["directory mask"] = 777,
456 -- ADD or set a share, and write to smb.conf
457 function smbshare
.set(share
, path
, readlist
, writelist
, comment
)
458 local conftable
= smbshare
.get()
459 local tb
= smbshare
.new()
462 tb
["readlist"] = ","..readlist
463 tb
["writelist"] = ","..writelist
464 tb
["comment"] = comment
465 conftable
[share
] = tb
466 smbshare
.put(conftable
)
469 -- REMOVE a share from smb.conf
470 function smbshare
.remove(share
)
471 local conftable
= smbshare
.get()
473 for s
, v
in pairs(conftable
) do
474 if s
~= share
then t
[s
] = v
end
479 -- return a local user table: {user,} = {uid,gid,comment,home,shell}
480 function get_local_user()
481 local fstr
= myread("/etc/passwd")
483 string.gsub(fstr
, "[%^\n](%S+):%S+:(%d+):(%d+):(.-):(%S+):([^\n]+)",
484 function(u
,uid
,gid
,c
,h
,s
)
485 if tonumber(uid
) >= 1000 then
486 tbl
[u
] = {["uid"] = uid
, ["gid"] = gid
, ["comment"] = c
, ["home"] = h
, ["shell"] = s
}
491 -- return a samba user table: {user = uid, }
492 function get_samba_user()
493 local fstr
= myexec("sudo /bin/cat /etc/samba/private/smbpasswd")
495 string.gsub(fstr
, "([%w_]+):(%d+)[^\n]+", function(u
,uid
) tbl
[u
] = uid
end)
498 -- smbshare.set("a new share", "/root/seconf", "nouser", "nogroup", "ok, comment")
499 -- smbshare.remove("a new share")
501 -- vim:ts=3 ss=3 sw=3 expandtab