Skip to content
Snippets Groups Projects
Select Git revision
  • b1aa5390a72bddbdad78b0661735f1813afeaac4
  • v2018.2.x default protected
  • 0x4A6F-rpi4
  • 0x4A6F-master
  • master
  • v2018.2.2-ffs
  • v2016.2.4-batmanbug
  • radv-filterd
  • v2016.2.x
  • hoodselector
  • v2016.1.x
  • babel
  • v2015.1.x
  • 2014.4.x
  • 2014.3.x
  • v2018.2.2-ffs0.1
  • v2018.2.1-ffs0.1
  • v2018.2.1
  • v2018.2-ffs0.1
  • v2018.2
  • v2018.1.4
  • v2018.1.3
  • v2018.1.2
  • v2018.1.1
  • v2018.1
  • v2017.1.8
  • v2017.1.7
  • v2017.1.6
  • v2017.1.5
  • v2017.1.4
  • v2017.1.3
  • v2017.1.2
  • v2016.2.7
  • v2017.1.1
  • v2017.1
35 results

upgrade.lua

Blame
  • Forked from firmware / FFS Gluon
    Source project has a limited visibility.
    upgrade.lua 3.57 KiB
    --[[
    Copyright 2008 Steven Barth <steven@midlink.org>
    Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
    
    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
    ]]--
    
    package 'gluon-web-admin'
    
    
    local util = require 'gluon.util'
    local fs = require 'nixio.fs'
    
    local tmpfile = "/tmp/firmware.img"
    
    
    local function filehandler(meta, chunk, eof)
    	if not fs.access(tmpfile) and not file and chunk and #chunk > 0 then
    		file = io.open(tmpfile, "w")
    	end
    	if file and chunk then
    		file:write(chunk)
    	end
    	if file and eof then
    		file:close()
    	end
    end
    
    local function action_upgrade(http, renderer)
    	local nixio = require 'nixio'
    
    	local function fork_exec(...)
    		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()
    				end
    			end
    
    			-- Sleep a little so the browser can fetch everything required to
    			-- display the reboot page, then reboot the device.
    			nixio.nanosleep(1)
    
    			-- replace with target command
    			nixio.exec(...)
    		end
    	end
    
    	local function image_supported(tmpfile)
    		return (os.execute(string.format("exec /sbin/sysupgrade -T %q >/dev/null", tmpfile)) == 0)
    	end
    
    	local function storage_size()
    		local size = 0
    		if 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" then
    					size = tonumber(s, 16)
    					break
    				end
    			end
    		elseif 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
    		end
    		return size
    	end
    
    	local function image_checksum(tmpfile)
    		return (util.exec(string.format("exec md5sum %q", tmpfile)):match("^([^%s]+)"))
    	end
    
    
    	-- Determine state
    	local step = tonumber(http:getenv("REQUEST_METHOD") == "POST" and http:formvalue("step")) or 1
    
    	local has_image   = fs.access(tmpfile)
    	local has_support = has_image and image_supported(tmpfile)
    
    	-- Step 1: file upload, error on unsupported image format
    	if step == 1 or not has_support then
    		-- If there is an image but user has requested step 1
    		-- or type is not supported, then remove it.
    		if has_image then
    			fs.unlink(tmpfile)
    		end
    
    		renderer.render_layout('admin/upgrade', {
    			bad_image = has_image and not has_support,
    		}, 'gluon-web-admin')
    
    	-- Step 2: present uploaded file, show checksum, confirmation
    	elseif step == 2 then
    		renderer.render_layout('admin/upgrade_confirm', {
    			checksum   = image_checksum(tmpfile),
    			filesize   = fs.stat(tmpfile).size,
    			flashsize  = storage_size(),
    			keepconfig = (http:formvalue("keepcfg") == "1"),
    		}, 'gluon-web-admin')
    
    	elseif step == 3 then
    		if http:formvalue("keepcfg") == "1" then
    			fork_exec("/sbin/sysupgrade", tmpfile)
    		else
    			fork_exec("/sbin/sysupgrade", "-n", tmpfile)
    		end
    		renderer.render_layout('admin/upgrade_reboot', nil, 'gluon-web-admin', {
    			hidenav = true,
    		})
    	end
    end
    
    
    local has_platform = fs.access("/lib/upgrade/platform.sh")
    if has_platform then
    	local upgrade = entry({"admin", "upgrade"}, call(action_upgrade), _("Upgrade firmware"), 90)
    	upgrade.filehandler = filehandler
    end