2008-06-08 08:14:31 +00:00
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth < steven @ midlink.org >
2011-12-20 17:35:50 +00:00
Copyright 2008 - 2011 Jo - Philipp Wich < xm @ subsignal.org >
2008-06-08 08:14:31 +00:00
Licensed under the Apache License , Version 2.0 ( the " License " ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : // www.apache . org / licenses / LICENSE - 2.0
$ Id $
] ] --
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 )
2011-10-24 01:10:34 +00:00
entry ( { " admin " , " system " , " clock_status " } , call ( " action_clock_status " ) )
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
2011-10-08 21:43:50 +00:00
entry ( { " admin " , " system " , " packages " } , call ( " action_packages " ) , _ ( " Software " ) , 10 )
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-01-15 14:37:46 +00:00
if fs.access ( " /etc/config/fstab " ) 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
2011-10-24 01:10:34 +00:00
entry ( { " admin " , " system " , " flashops " } , call ( " action_flashops " ) , _ ( " Backup / Flash Firmware " ) , 70 )
entry ( { " admin " , " system " , " flashops " , " backupfiles " } , form ( " admin_system/backupfiles " ) )
2011-08-12 13:16:27 +00:00
entry ( { " admin " , " system " , " reboot " } , call ( " action_reboot " ) , _ ( " Reboot " ) , 90 )
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 ( )
2008-06-05 19:16:38 +00:00
local ipkg = require ( " luci.model.ipkg " )
2008-05-25 17:00:30 +00:00
local submit = luci.http . formvalue ( " submit " )
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
2008-04-11 18:24:25 +00:00
-- Packets to be installed
2010-04-18 22:55:59 +00:00
local ninst = submit and luci.http . formvalue ( " install " )
2010-11-23 22:38:01 +00:00
local uinst = nil
2010-04-18 22:55:59 +00:00
2008-04-11 18:24:25 +00:00
-- Install from URL
2008-05-25 17:00:30 +00:00
local url = luci.http . formvalue ( " url " )
2008-04-11 18:24:25 +00:00
if url and url ~= ' ' and submit then
2010-04-18 22:55:59 +00:00
uinst = url
2008-04-11 18:24:25 +00:00
end
2010-04-18 22:55:59 +00:00
2008-05-05 19:27:30 +00:00
-- Do install
2010-04-18 22:55:59 +00:00
if ninst then
2011-06-23 10:14:26 +00:00
install [ ninst ] , out , err = ipkg.install ( ninst )
stdout [ # stdout + 1 ] = out
stderr [ # stderr + 1 ] = err
2009-05-30 01:20:07 +00:00
changes = true
2008-04-11 18:24:25 +00:00
end
2010-04-18 22:55:59 +00:00
if uinst then
2011-10-15 05:27:06 +00:00
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
2010-04-18 22:55:59 +00:00
end
2008-04-11 18:24:25 +00:00
-- Remove packets
2010-04-18 22:55:59 +00:00
local rem = submit and luci.http . formvalue ( " remove " )
2010-11-23 22:38:01 +00:00
if rem then
2011-06-23 10:14:26 +00:00
remove [ rem ] , out , err = ipkg.remove ( rem )
stdout [ # stdout + 1 ] = out
stderr [ # stderr + 1 ] = err
2009-05-30 01:20:07 +00:00
changes = true
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
2008-04-11 18:24:25 +00:00
-- Update all packets
2008-05-25 17:00:30 +00:00
local update = luci.http . formvalue ( " update " )
2008-04-11 18:24:25 +00:00
if update then
2011-06-23 10:14:26 +00:00
update , out , err = ipkg.update ( )
stdout [ # stdout + 1 ] = out
stderr [ # stderr + 1 ] = err
2008-04-11 18:24:25 +00:00
end
2010-11-23 22:38:01 +00:00
2008-04-11 18:24:25 +00:00
-- Upgrade all packets
2008-05-25 17:00:30 +00:00
local upgrade = luci.http . formvalue ( " upgrade " )
2008-04-11 18:24:25 +00:00
if upgrade then
2011-06-23 10:14:26 +00:00
upgrade , out , err = ipkg.upgrade ( )
stdout [ # stdout + 1 ] = out
stderr [ # stderr + 1 ] = err
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
2011-10-24 01:10:34 +00:00
function action_flashops ( )
2010-11-24 13:42:20 +00:00
local sys = require " luci.sys "
2015-01-15 14:37:46 +00:00
local fs = require " nixio.fs "
2010-11-24 13:42:20 +00:00
2015-01-15 14:37:46 +00:00
local upgrade_avail = fs.access ( " /lib/upgrade/platform.sh " )
2011-10-24 01:10:34 +00:00
local reset_avail = os.execute ( [[grep '"rootfs_data"' /proc/mtd >/dev/null 2>&1]] ) == 0
2009-07-01 14:17:59 +00:00
local restore_cmd = " tar -xzC/ >/dev/null 2>&1 "
2011-12-20 17:35:50 +00:00
local backup_cmd = " sysupgrade --create-backup - 2>/dev/null "
2011-10-24 01:10:34 +00:00
local image_tmp = " /tmp/firmware.img "
local function image_supported ( )
-- XXX: yay...
return ( 0 == os.execute (
2012-12-20 15:01:04 +00:00
" . /lib/functions.sh; " ..
2011-10-24 01:10:34 +00:00
" include /lib/upgrade; " ..
" platform_check_image %q >/dev/null "
% image_tmp
) )
end
local function image_checksum ( )
return ( luci.sys . exec ( " md5sum %q " % image_tmp ) : match ( " ^([^%s]+) " ) )
end
local function storage_size ( )
local size = 0
2015-01-15 14:37:46 +00:00
if fs.access ( " /proc/mtd " ) then
2011-10-24 01:10:34 +00:00
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
2015-01-15 14:37:46 +00:00
elseif fs.access ( " /proc/partitions " ) then
2011-10-24 01:10:34 +00:00
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
end
return size
end
2009-07-01 14:17:59 +00:00
2011-10-24 01:10:34 +00:00
local fp
2008-08-03 15:01:36 +00:00
luci.http . setfilehandler (
function ( meta , chunk , eof )
2011-10-24 01:10:34 +00:00
if not fp then
if meta and meta.name == " image " then
fp = io.open ( image_tmp , " w " )
else
fp = io.popen ( restore_cmd , " w " )
end
2008-08-03 15:01:36 +00:00
end
if chunk then
2011-10-24 01:10:34 +00:00
fp : write ( chunk )
2008-08-03 15:01:36 +00:00
end
if eof then
2011-10-24 01:10:34 +00:00
fp : close ( )
2008-08-03 15:01:36 +00:00
end
end
)
2010-11-23 22:38:01 +00:00
2011-10-24 01:10:34 +00:00
if luci.http . formvalue ( " backup " ) then
--
-- Assemble file list, generate backup
--
2011-12-20 17:35:50 +00:00
local reader = ltn12_popen ( backup_cmd )
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 )
2011-10-24 01:10:34 +00:00
elseif luci.http . formvalue ( " restore " ) then
--
-- Unpack received .tar.gz
--
local upload = luci.http . formvalue ( " archive " )
if upload and # upload > 0 then
luci.template . render ( " admin_system/applyreboot " )
luci.sys . reboot ( )
end
elseif luci.http . formvalue ( " image " ) or luci.http . formvalue ( " step " ) then
--
-- Initiate firmware flash
--
local step = tonumber ( luci.http . formvalue ( " step " ) or 1 )
if step == 1 then
if image_supported ( ) then
luci.template . render ( " admin_system/upgrade " , {
checksum = image_checksum ( ) ,
storage = storage_size ( ) ,
2015-01-15 14:37:46 +00:00
size = ( fs.stat ( image_tmp , " size " ) or 0 ) ,
2011-10-24 01:10:34 +00:00
keep = ( not not luci.http . formvalue ( " keep " ) )
} )
else
2015-01-15 14:37:46 +00:00
fs.unlink ( image_tmp )
2011-10-24 01:10:34 +00:00
luci.template . render ( " admin_system/flashops " , {
reset_avail = reset_avail ,
upgrade_avail = upgrade_avail ,
image_invalid = true
} )
end
--
-- Start sysupgrade flash
--
elseif step == 2 then
local keep = ( luci.http . formvalue ( " keep " ) == " 1 " ) and " " or " -n "
luci.template . render ( " admin_system/applyreboot " , {
title = luci.i18n . translate ( " Flashing... " ) ,
2014-08-05 10:21:03 +00:00
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. " ) ,
2011-10-24 01:10:34 +00:00
addr = ( # keep > 0 ) and " 192.168.1.1 " or nil
} )
fork_exec ( " killall dropbear uhttpd; sleep 1; /sbin/sysupgrade %s %q " % { keep , image_tmp } )
end
elseif reset_avail and luci.http . formvalue ( " reset " ) then
--
-- Reset system
--
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 "
} )
fork_exec ( " killall dropbear uhttpd; sleep 1; mtd -r erase rootfs_data " )
2008-08-03 15:01:36 +00:00
else
2011-10-24 01:10:34 +00:00
--
-- Overview
--
luci.template . render ( " admin_system/flashops " , {
reset_avail = reset_avail ,
upgrade_avail = upgrade_avail
} )
2008-08-03 15:01:36 +00:00
end
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 ( )
2008-05-25 17:00:30 +00:00
local reboot = luci.http . formvalue ( " reboot " )
luci.template . render ( " admin_system/reboot " , { reboot = reboot } )
2008-04-11 18:24:25 +00:00
if reboot then
2008-05-25 17:00:30 +00:00
luci.sys . reboot ( )
2008-04-11 18:24:25 +00:00
end
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