2015-01-16 22:38:38 +00:00
-- Copyright 2008 Steven Barth <steven@midlink.org>
2015-01-16 22:46:42 +00:00
-- Copyright 2008-2011 Jo-Philipp Wich <jow@openwrt.org>
2015-01-16 22:38:38 +00:00
-- Licensed to the public under the Apache License 2.0.
2010-11-24 13:42:20 +00:00
2008-05-25 17:00:30 +00:00
module ( " luci.controller.admin.system " , package.seeall )
2008-04-11 18:24:25 +00:00
2008-05-22 14:04:03 +00:00
function index ( )
2015-01-15 14:37:46 +00:00
local fs = require " nixio.fs "
2011-08-12 13:16:27 +00:00
entry ( { " admin " , " system " } , alias ( " admin " , " system " , " system " ) , _ ( " System " ) , 30 ) . index = true
entry ( { " admin " , " system " , " system " } , cbi ( " admin_system/system " ) , _ ( " System " ) , 1 )
2015-10-20 19:01:41 +00:00
entry ( { " admin " , " system " , " clock_status " } , post_on ( { set = true } , " action_clock_status " ) )
2011-10-24 01:10:34 +00:00
2011-08-12 13:16:27 +00:00
entry ( { " admin " , " system " , " admin " } , cbi ( " admin_system/admin " ) , _ ( " Administration " ) , 2 )
2011-10-08 21:43:50 +00:00
2015-01-15 14:37:46 +00:00
if fs.access ( " /bin/opkg " ) then
2015-10-20 19:01:41 +00:00
entry ( { " admin " , " system " , " packages " } , post_on ( { exec = " 1 " } , " action_packages " ) , _ ( " Software " ) , 10 )
2011-10-08 21:43:50 +00:00
entry ( { " admin " , " system " , " packages " , " ipkg " } , form ( " admin_system/ipkg " ) )
end
2011-08-12 13:16:27 +00:00
entry ( { " admin " , " system " , " startup " } , form ( " admin_system/startup " ) , _ ( " Startup " ) , 45 )
2011-10-26 00:58:12 +00:00
entry ( { " admin " , " system " , " crontab " } , form ( " admin_system/crontab " ) , _ ( " Scheduled Tasks " ) , 46 )
2010-03-08 02:16:38 +00:00
2015-04-12 18:20:01 +00:00
if fs.access ( " /sbin/block " ) then
2011-08-12 13:16:27 +00:00
entry ( { " admin " , " system " , " fstab " } , cbi ( " admin_system/fstab " ) , _ ( " Mount Points " ) , 50 )
2010-11-27 04:55:38 +00:00
entry ( { " admin " , " system " , " fstab " , " mount " } , cbi ( " admin_system/fstab/mount " ) , nil ) . leaf = true
entry ( { " admin " , " system " , " fstab " , " swap " } , cbi ( " admin_system/fstab/swap " ) , nil ) . leaf = true
2010-03-08 02:16:38 +00:00
end
2008-12-19 12:12:43 +00:00
2015-01-15 14:37:46 +00:00
if fs.access ( " /sys/class/leds " ) then
2011-08-12 13:16:27 +00:00
entry ( { " admin " , " system " , " leds " } , cbi ( " admin_system/leds " ) , _ ( " <abbr title= \" Light Emitting Diode \" >LED</abbr> Configuration " ) , 60 )
2008-12-19 12:12:43 +00:00
end
2015-10-22 06:35:34 +00:00
entry ( { " admin " , " system " , " flashops " } , call ( " action_flashops " ) , _ ( " Backup / Flash Firmware " ) , 70 )
entry ( { " admin " , " system " , " flashops " , " reset " } , post ( " action_reset " ) )
entry ( { " admin " , " system " , " flashops " , " backup " } , post ( " action_backup " ) )
2011-10-24 01:10:34 +00:00
entry ( { " admin " , " system " , " flashops " , " backupfiles " } , form ( " admin_system/backupfiles " ) )
2015-10-22 06:35:34 +00:00
-- call() instead of post() due to upload handling!
entry ( { " admin " , " system " , " flashops " , " restore " } , call ( " action_restore " ) )
entry ( { " admin " , " system " , " flashops " , " sysupgrade " } , call ( " action_sysupgrade " ) )
2015-10-06 23:54:56 +00:00
entry ( { " admin " , " system " , " reboot " } , template ( " admin_system/reboot " ) , _ ( " Reboot " ) , 90 )
entry ( { " admin " , " system " , " reboot " , " call " } , post ( " action_reboot " ) )
2008-05-22 14:04:03 +00:00
end
2011-10-24 01:10:34 +00:00
function action_clock_status ( )
local set = tonumber ( luci.http . formvalue ( " set " ) )
if set ~= nil and set > 0 then
local date = os.date ( " *t " , set )
if date then
luci.sys . call ( " date -s '%04d-%02d-%02d %02d:%02d:%02d' " % {
date.year , date.month , date.day , date.hour , date.min , date.sec
} )
end
end
luci.http . prepare_content ( " application/json " )
luci.http . write_json ( { timestring = os.date ( " %c " ) } )
end
2008-04-11 18:24:25 +00:00
function action_packages ( )
2015-01-15 15:34:48 +00:00
local fs = require " nixio.fs "
local ipkg = require " luci.model.ipkg "
2015-10-20 19:01:41 +00:00
local submit = ( luci.http . formvalue ( " exec " ) == " 1 " )
local update , upgrade
2009-05-30 01:20:07 +00:00
local changes = false
2010-04-18 22:55:59 +00:00
local install = { }
local remove = { }
2011-06-23 10:14:26 +00:00
local stdout = { " " }
local stderr = { " " }
local out , err
2010-04-18 22:55:59 +00:00
2011-10-15 03:13:49 +00:00
-- Display
local display = luci.http . formvalue ( " display " ) or " installed "
-- Letter
local letter = string.byte ( luci.http . formvalue ( " letter " ) or " A " , 1 )
letter = ( letter == 35 or ( letter >= 65 and letter <= 90 ) ) and letter or 65
2008-04-11 18:24:25 +00:00
-- Search query
2008-05-25 17:00:30 +00:00
local query = luci.http . formvalue ( " query " )
2008-04-11 18:24:25 +00:00
query = ( query ~= ' ' ) and query or nil
2010-11-23 22:38:01 +00:00
2015-10-20 19:01:41 +00:00
-- Modifying actions
if submit then
-- Packets to be installed
local ninst = luci.http . formvalue ( " install " )
local uinst = nil
2010-04-18 22:55:59 +00:00
2015-10-20 19:01:41 +00:00
-- Install from URL
local url = luci.http . formvalue ( " url " )
if url and url ~= ' ' then
uinst = url
end
2010-04-18 22:55:59 +00:00
2015-10-20 19:01:41 +00:00
-- Do install
if ninst then
install [ ninst ] , out , err = ipkg.install ( ninst )
2011-10-15 05:27:06 +00:00
stdout [ # stdout + 1 ] = out
stderr [ # stderr + 1 ] = err
changes = true
end
2010-04-18 22:55:59 +00:00
2015-10-20 19:01:41 +00:00
if uinst then
local pkg
for pkg in luci.util . imatch ( uinst ) do
install [ uinst ] , out , err = ipkg.install ( pkg )
stdout [ # stdout + 1 ] = out
stderr [ # stderr + 1 ] = err
changes = true
end
end
2010-04-18 22:55:59 +00:00
2015-10-20 19:01:41 +00:00
-- Remove packets
local rem = luci.http . formvalue ( " remove " )
if rem then
remove [ rem ] , out , err = ipkg.remove ( rem )
stdout [ # stdout + 1 ] = out
stderr [ # stderr + 1 ] = err
changes = true
end
2010-11-23 22:38:01 +00:00
2015-10-20 19:01:41 +00:00
-- Update all packets
update = luci.http . formvalue ( " update " )
if update then
update , out , err = ipkg.update ( )
stdout [ # stdout + 1 ] = out
stderr [ # stderr + 1 ] = err
end
2010-11-23 22:38:01 +00:00
2015-10-20 19:01:41 +00:00
-- Upgrade all packets
upgrade = luci.http . formvalue ( " upgrade " )
if upgrade then
upgrade , out , err = ipkg.upgrade ( )
stdout [ # stdout + 1 ] = out
stderr [ # stderr + 1 ] = err
end
2008-04-11 18:24:25 +00:00
end
2010-04-18 22:55:59 +00:00
2010-11-23 22:38:01 +00:00
2011-10-24 01:10:34 +00:00
-- List state
local no_lists = true
local old_lists = false
2015-01-15 14:37:46 +00:00
if fs.access ( " /var/opkg-lists/ " ) then
local list
for list in fs.dir ( " /var/opkg-lists/ " ) do
2011-10-24 01:10:34 +00:00
no_lists = false
2015-01-15 14:37:46 +00:00
if ( fs.stat ( " /var/opkg-lists/ " .. list , " mtime " ) or 0 ) < ( os.time ( ) - ( 24 * 60 * 60 ) ) then
2011-10-24 01:10:34 +00:00
old_lists = true
break
end
end
end
2010-04-18 22:55:59 +00:00
luci.template . render ( " admin_system/packages " , {
2011-10-24 01:10:34 +00:00
display = display ,
letter = letter ,
query = query ,
install = install ,
remove = remove ,
update = update ,
upgrade = upgrade ,
no_lists = no_lists ,
old_lists = old_lists ,
stdout = table.concat ( stdout , " " ) ,
stderr = table.concat ( stderr , " " )
2010-04-18 22:55:59 +00:00
} )
2010-11-23 22:38:01 +00:00
2009-05-30 01:20:07 +00:00
-- Remove index cache
if changes then
2015-01-15 14:37:46 +00:00
fs.unlink ( " /tmp/luci-indexcache " )
2010-11-23 22:38:01 +00:00
end
2008-04-11 18:24:25 +00:00
end
2015-10-22 06:35:34 +00:00
local function image_supported ( image )
return ( os.execute ( " sysupgrade -T %q >/dev/null " % image ) == 0 )
end
2015-10-20 19:01:41 +00:00
2015-10-22 06:35:34 +00:00
local function image_checksum ( image )
return ( luci.sys . exec ( " md5sum %q " % image ) : match ( " ^([^%s]+) " ) )
end
2010-11-24 13:42:20 +00:00
2015-10-22 06:35:34 +00:00
local function supports_sysupgrade ( )
return nixio.fs . access ( " /lib/upgrade/platform.sh " )
end
2011-10-24 01:10:34 +00:00
2015-10-22 06:35:34 +00:00
local function supports_reset ( )
2016-03-23 14:58:14 +00:00
return ( os.execute ( [[grep -sqE '"rootfs_data"|"ubi"' /proc/mtd]] ) == 0 )
2015-10-22 06:35:34 +00:00
end
2011-10-24 01:10:34 +00:00
2015-10-22 06:35:34 +00:00
local function storage_size ( )
local size = 0
if nixio.fs . access ( " /proc/mtd " ) then
for l in io.lines ( " /proc/mtd " ) do
local d , s , e , n = l : match ( ' ^([^%s]+)%s+([^%s]+)%s+([^%s]+)%s+"([^%s]+)" ' )
if n == " linux " or n == " firmware " then
size = tonumber ( s , 16 )
break
end
end
elseif nixio.fs . access ( " /proc/partitions " ) then
for l in io.lines ( " /proc/partitions " ) do
local x , y , b , n = l : match ( ' ^%s*(%d+)%s+(%d+)%s+([^%s]+)%s+([^%s]+) ' )
if b and n and not n : match ( ' [0-9] ' ) then
size = tonumber ( b ) * 1024
break
end
end
2011-10-24 01:10:34 +00:00
end
2015-10-22 06:35:34 +00:00
return size
end
2011-10-24 01:10:34 +00:00
2015-10-22 06:35:34 +00:00
function action_flashops ( )
--
-- Overview
--
luci.template . render ( " admin_system/flashops " , {
reset_avail = supports_reset ( ) ,
upgrade_avail = supports_sysupgrade ( )
} )
end
function action_sysupgrade ( )
local fs = require " nixio.fs "
local http = require " luci.http "
local image_tmp = " /tmp/firmware.img "
local fp
http.setfilehandler (
function ( meta , chunk , eof )
if not fp and meta and meta.name == " image " then
fp = io.open ( image_tmp , " w " )
2011-10-24 01:10:34 +00:00
end
2015-10-22 06:35:34 +00:00
if fp and chunk then
fp : write ( chunk )
end
if fp and eof then
fp : close ( )
2011-10-24 01:10:34 +00:00
end
end
2015-10-22 06:35:34 +00:00
)
if not luci.dispatcher . test_post_security ( ) then
fs.unlink ( image_tmp )
return
2011-10-24 01:10:34 +00:00
end
2015-10-20 19:01:41 +00:00
--
2015-10-22 06:35:34 +00:00
-- Cancel firmware flash
2015-10-20 19:01:41 +00:00
--
2015-10-22 06:35:34 +00:00
if http.formvalue ( " cancel " ) then
fs.unlink ( image_tmp )
http.redirect ( luci.dispatcher . build_url ( ' admin/system/flashops ' ) )
return
end
2015-10-20 19:01:41 +00:00
2015-10-22 06:35:34 +00:00
--
-- Initiate firmware flash
--
local step = tonumber ( http.formvalue ( " step " ) or 1 )
if step == 1 then
if image_supported ( image_tmp ) then
luci.template . render ( " admin_system/upgrade " , {
checksum = image_checksum ( image_tmp ) ,
storage = storage_size ( ) ,
size = ( fs.stat ( image_tmp , " size " ) or 0 ) ,
keep = ( not not http.formvalue ( " keep " ) )
} )
else
fs.unlink ( image_tmp )
luci.template . render ( " admin_system/flashops " , {
reset_avail = supports_reset ( ) ,
upgrade_avail = supports_sysupgrade ( ) ,
image_invalid = true
} )
end
--
-- Start sysupgrade flash
--
elseif step == 2 then
local keep = ( http.formvalue ( " keep " ) == " 1 " ) and " " or " -n "
luci.template . render ( " admin_system/applyreboot " , {
title = luci.i18n . translate ( " Flashing... " ) ,
msg = luci.i18n . translate ( " The system is flashing now.<br /> DO NOT POWER OFF THE DEVICE!<br /> Wait a few minutes before you try to reconnect. It might be necessary to renew the address of your computer to reach the device again, depending on your settings. " ) ,
addr = ( # keep > 0 ) and " 192.168.1.1 " or nil
} )
2016-03-17 14:55:02 +00:00
fork_exec ( " sleep 1; killall dropbear uhttpd; sleep 1; /sbin/sysupgrade %s %q " % { keep , image_tmp } )
2015-10-22 06:35:34 +00:00
end
end
function action_backup ( )
local reader = ltn12_popen ( " sysupgrade --create-backup - 2>/dev/null " )
luci.http . header (
' Content-Disposition ' , ' attachment; filename="backup-%s-%s.tar.gz" ' % {
luci.sys . hostname ( ) ,
os.date ( " %Y-%m-%d " )
} )
luci.http . prepare_content ( " application/x-targz " )
luci.ltn12 . pump.all ( reader , luci.http . write )
end
function action_restore ( )
local fs = require " nixio.fs "
local http = require " luci.http "
local archive_tmp = " /tmp/restore.tar.gz "
local fp
http.setfilehandler (
function ( meta , chunk , eof )
if not fp and meta and meta.name == " archive " then
fp = io.open ( archive_tmp , " w " )
2008-08-03 15:01:36 +00:00
end
2015-10-22 06:35:34 +00:00
if fp and chunk then
fp : write ( chunk )
2008-08-03 15:01:36 +00:00
end
2015-10-22 06:35:34 +00:00
if fp and eof then
fp : close ( )
2011-10-24 01:10:34 +00:00
end
end
2015-10-22 06:35:34 +00:00
)
if not luci.dispatcher . test_post_security ( ) then
fs.unlink ( archive_tmp )
return
2008-08-03 15:01:36 +00:00
end
2015-10-20 19:01:41 +00:00
2015-10-22 06:35:34 +00:00
local upload = http.formvalue ( " archive " )
if upload and # upload > 0 then
luci.template . render ( " admin_system/applyreboot " )
os.execute ( " tar -C / -xzf %q >/dev/null 2>&1 " % archive_tmp )
luci.sys . reboot ( )
return
end
http.redirect ( luci.dispatcher . build_url ( ' admin/system/flashops ' ) )
end
function action_reset ( )
if supports_reset ( ) then
luci.template . render ( " admin_system/applyreboot " , {
title = luci.i18n . translate ( " Erasing... " ) ,
msg = luci.i18n . translate ( " The system is erasing the configuration partition now and will reboot itself when finished. " ) ,
addr = " 192.168.1.1 "
} )
2016-03-23 14:58:14 +00:00
fork_exec ( " sleep 1; killall dropbear uhttpd; sleep 1; jffs2reset -y && reboot " )
2015-10-22 06:35:34 +00:00
return
end
http.redirect ( luci.dispatcher . build_url ( ' admin/system/flashops ' ) )
2008-08-03 15:01:36 +00:00
end
2008-04-11 18:24:25 +00:00
function action_passwd ( )
2008-05-25 17:00:30 +00:00
local p1 = luci.http . formvalue ( " pwd1 " )
local p2 = luci.http . formvalue ( " pwd2 " )
2008-04-11 18:24:25 +00:00
local stat = nil
2010-11-23 22:38:01 +00:00
2008-04-11 18:24:25 +00:00
if p1 or p2 then
if p1 == p2 then
2008-05-25 17:00:30 +00:00
stat = luci.sys . user.setpasswd ( " root " , p1 )
2008-04-11 18:24:25 +00:00
else
stat = 10
end
end
2010-11-23 22:38:01 +00:00
2008-05-25 17:00:30 +00:00
luci.template . render ( " admin_system/passwd " , { stat = stat } )
2008-04-11 18:24:25 +00:00
end
function action_reboot ( )
2015-10-06 23:54:56 +00:00
luci.sys . reboot ( )
2008-04-11 18:24:25 +00:00
end
2011-10-24 01:10:34 +00:00
function fork_exec ( command )
local pid = nixio.fork ( )
if pid > 0 then
return
elseif pid == 0 then
-- change to root dir
nixio.chdir ( " / " )
-- patch stdin, out, err to /dev/null
local null = nixio.open ( " /dev/null " , " w+ " )
if null then
nixio.dup ( null , nixio.stderr )
nixio.dup ( null , nixio.stdout )
nixio.dup ( null , nixio.stdin )
if null : fileno ( ) > 2 then
null : close ( )
2008-07-16 14:26:40 +00:00
end
end
2009-05-09 02:06:33 +00:00
2011-10-24 01:10:34 +00:00
-- replace with target command
nixio.exec ( " /bin/sh " , " -c " , command )
2008-08-03 15:01:36 +00:00
end
2008-09-06 18:55:26 +00:00
end
2009-07-01 14:17:59 +00:00
function ltn12_popen ( command )
local fdi , fdo = nixio.pipe ( )
local pid = nixio.fork ( )
if pid > 0 then
fdo : close ( )
local close
return function ( )
local buffer = fdi : read ( 2048 )
local wpid , stat = nixio.waitpid ( pid , " nohang " )
if not close and wpid and stat == " exited " then
close = true
end
if buffer and # buffer > 0 then
return buffer
elseif close then
fdi : close ( )
return nil
end
end
elseif pid == 0 then
nixio.dup ( fdo , nixio.stdout )
fdi : close ( )
fdo : close ( )
nixio.exec ( " /bin/sh " , " -c " , command )
end
end