-
-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$
-]]--
-
-local io = require "io"
-local os = require "os"
-local fs = require "luci.fs"
-local util = require "luci.util"
-local ltn12 = require "luci.ltn12"
-local posix = require "posix"
-
-local type, assert, error, ipairs = type, assert, error, ipairs
-
-module "luci.sys.mtdow"
-
-WRITE_IMAGE = 0
-WRITE_COMBINED = 1
-WRITE_EMULATED = 2
-
-ERROR_INTERNAL = 1
-ERROR_NOTFOUND = 2
-ERROR_RESOURCE = 3
-ERROR_NODETECT = 4
-ERROR_NOTAVAIL = 5
-ERROR_NOSTREAM = 6
-ERROR_INVMAGIC = 7
-
-Writer = util.class()
-
--- x86
-EmulatedWriter = util.class(Writer)
-EmulatedWriter.blocks = {
- image = {
- magic = "eb48",
- device = "/dev/hda",
- write = WRITE_EMULATED
- }
-}
-
-function EmulatedWriter.write_block(self, name, imagestream, appendpattern)
- if appendpattern then
- os.execute("grep rootfs /proc/mtd >/dev/null || "
- .. "{ echo /dev/hda2,65536,rootfs > "
- .. "/sys/module/block2mtd/parameters/block2mtd }")
- end
- return Writer.write_block(self, name, imagestream, appendpattern)
-end
-
--- Broadcom
-CFEWriter = util.class(Writer)
-CFEWriter.blocks = {
- image = {
- magic = {"4844", "5735"},
- device = "linux",
- write = WRITE_IMAGE,
- system = true
- }
-}
-
--- Magicbox
-CommonWriter = util.class(Writer)
-CommonWriter.blocks = {
- image = {
- device = "linux",
- write = WRITE_COMBINED,
- system = true
- }
-}
-
--- Atheros
-RedWriter = util.class(Writer)
-RedWriter.blocks = {
- kernel = {
- device = "vmlinux.bin.l7",
- write = WRITE_IMAGE
- },
- rootfs = {
- device = "rootfs",
- write = WRITE_COMBINED,
- system = true
- }
-}
-
--- Auto Detect
-function native_writer()
- local w = Writer()
-
- -- Detect amd64 / x86
- local x86 = {"x86_64", "i386", "i486", "i586", "i686"}
- if util.contains(x86, posix.uname("%m")) then
- return EmulatedWriter()
- end
-
- -- Detect CFE
- if w:_find_mtdblock("cfe") and w:_find_mtdblock("linux") then
- return CFEWriter()
- end
-
- -- Detect Redboot
- if w:_find_mtdblock("RedBoot") and w:_find_mtdblock("vmlinux.bin.l7") then
- return RedWriter()
- end
-
- -- Detect MagicBox
- if fs.readfile("/proc/cpuinfo"):find("MagicBox") then
- return CommonWriter()
- end
-end
-
-
-
-Writer.COPY = {"/sbin/mtd"}
-Writer.MTD = "/tmp/mtd"
-Writer.IMAGEFIFO = "/tmp/mtdimage.fifo"
-
-
-function Writer.write_block(self, name, imagestream, appendfile)
- assert(self.blocks[name], ERROR_NOTFOUND)
- local block = self.blocks[name]
- local device = block.device
- device = fs.stat(device) and device or self:_find_mtdblock(device)
- assert(device, ERROR_NODETECT)
- if block.magic then
- imagestream = self:_check_magic(imagestream, block.magic)
- end
- assert(imagestream, ERROR_INVMAGIC)
-
- self:_prepare_env()
-
- if appendfile then
- if block.write == WRITE_COMBINED then
- return (self:_write_combined(device, imagestream, appendfile) == 0)
- elseif block.write == WRITE_EMULATED then
- return (self:_write_emulated(device, imagestream, appendfile) == 0)
- else
- error(ERROR_NOTAVAIL)
- end
- else
- return (self:_write_memory(device, imagestream) == 0)
- end
-end
-
-function Writer._prepare_env(self)
- if self._prepared then
- return
- end
-
- for k, app in ipairs(self.COPY) do
- local target = "/tmp/"..fs.basename(app)
- fs.unlink(target)
- fs.copy(app, target)
- fs.chmod(target, "rwx------")
- end
-
- self._prepared = true
-end
-
-function Writer._check_magic(self, imagestream, magic)
- magic = type(magic) == "table" and magic or {magic}
-
- local block = imagestream()
- assert(block, ERROR_NOSTREAM)
- local cm = "%x%x" % {block:byte(1), block:byte(2)}
-
- if util.contains(magic, cm) then
- return ltn12.source.cat(ltn12.source.string(block), imagestream)
- end
-end
-
-function Writer._find_mtdblock(self, mtdname)
- local k
- local prefix = "/dev/mtd"
- prefix = prefix .. (fs.stat(prefix) and "/" or "")
-
- for l in io.lines("/proc/mtd") do
- local k = l:match('mtd([%%w-_]+):.*"%s"' % mtdname)
- if k then return prefix..k end
- end
-end
-
-function Writer._write_emulated(self, devicename, imagestream, appendfile)
- local stat = (self:_write_memory(device, imagestream) == 0)
- stat = stat and (self:_refresh_block("rootfs") == 0)
- local squash = self:_find_mtdblock("rootfs_data")
- if squash then
- stat = stat and (self:_append("rootfs_data", imagestream, true) == 0)
- else
- stat = stat and (self:_append("rootfs", imagestream) == 0)
- end
- return stat
-end
-
-function Writer._write_memory(self, devicename, imagestream)
- local imageproc = posix.fork()
- assert(imageproc ~= -1, ERROR_RESOURCE)
- if imageproc == 0 then
- fs.unlink(self.IMAGEFIFO)
- assert(posix.mkfifo(self.IMAGEFIFO), ERROR_RESOURCE)
- local imagefifo = io.open(self.IMAGEFIFO, "w")
- assert(imagefifo, ERROR_RESOURCE)
- ltn12.pump.all(imagestream, ltn12.sink.file(imagefifo))
- os.exit(0)
- end
-
- return os.execute(
- "%s write '%s' '%s' >/dev/null 2>&1" % {
- self.MTD, self.IMAGEFIFO, devicename
- }
- )
-end
-
-function Writer._write_combined(self, devicename, imagestream, appendfile)
- local imageproc = posix.fork()
- assert(imageproc ~= -1, ERROR_RESOURCE)
- if imageproc == 0 then
- fs.unlink(self.IMAGEFIFO)
- assert(posix.mkfifo(self.IMAGEFIFO), ERROR_RESOURCE)
- local imagefifo = io.open(self.IMAGEFIFO, "w")
- assert(imagefifo, ERROR_RESOURCE)
- ltn12.pump.all(imagestream, ltn12.sink.file(imagefifo))
- os.exit(0)
- end
-
- return os.execute(
- "%s -j '%s' write '%s' '%s' >/dev/null 2>&1" % {
- self.MTD, appendfile, self.IMAGEFIFO, devicename
- }
- )
-end
-
-function Writer._refresh_block(self, devicename)
- return os.execute("%s refresh '%s' >/dev/null 2>&1" % {self.MTD, devicename})
-end
-
-function Writer._append(self, devicename, appendfile, erase)
- erase = erase and ("-e '%s' " % devicename) or ''
-
- return os.execute(
- "%s %s jffs2write '%s' '%s' >/dev/null 2>&1" % {
- self.MTD, erase, appendfile, devicename
- }
- )
-end
\ No newline at end of file
diff --git a/modules/admin-full/luasrc/controller/admin/system.lua b/modules/admin-full/luasrc/controller/admin/system.lua
index b99ca441b5..c89c5859b9 100644
--- a/modules/admin-full/luasrc/controller/admin/system.lua
+++ b/modules/admin-full/luasrc/controller/admin/system.lua
@@ -181,92 +181,50 @@ end
function action_upgrade()
require("luci.model.uci")
- local mtdow = require "luci.sys.mtdow"
- local writer = mtdow.native_writer()
- local blocks = writer and writer.blocks
- local ltn12 = require "luci.ltn12"
- local uploads = {}
- local flash = {}
-
- writer.COPY[#writer.COPY + 1] = "/sbin/reboot"
local ret
- local filepat = "/tmp/mtdblock.%s"
- local kfile = "/tmp/mtdappend.tgz"
-
- local keep_avail = false
- if blocks then
- for k, block in pairs(blocks) do
- if block.write ~= mtdow.WRITE_IMAGE then
- keep_avail = true
- end
- end
- end
+ local plat = luci.fs.mtime("/lib/upgrade/platform.sh")
+ local tmpfile = "/tmp/firmware.img"
+ local broadcom = os.execute('grep brcm_ /lib/upgrade/platform.sh >/dev/null 2>&1') == 0
+
+ local keep_avail = not broadcom
+ local file
luci.http.setfilehandler(
function(meta, chunk, eof)
- if not meta or not blocks or not blocks[meta.name] then
- return
- end
- if not uploads[meta.name] then
- uploads[meta.name] = io.open(filepat % meta.name, "w")
+ if not file then
+ file = io.open(tmpfile, "w")
end
if chunk then
- uploads[meta.name]:write(chunk)
+ file:write(chunk)
end
if eof then
- uploads[meta.name]:close()
- uploads[meta.name] = filepat % meta.name
+ file:close()
end
end
)
- luci.http.formvalue() -- Parse uploads
+ local fname = luci.http.formvalue("image")
local keepcfg = keep_avail and luci.http.formvalue("keepcfg")
-
- local function _kfile()
- luci.fs.unlink(kfile)
-
- local kpattern = ""
- local files = luci.model.uci.cursor():get_all("luci", "flash_keep")
- if files then
- kpattern = ""
- for k, v in pairs(files) do
- if k:sub(1,1) ~= "." and luci.fs.glob(v) then
- kpattern = kpattern .. " '" .. v .. "'"
- end
- end
+
+ if plat and fname then
+ ret = function()
+ return luci.sys.flash(tmpfile, keepcfg and _keep_pattern())
end
-
- local stat = os.execute("tar czf '%s' %s >/dev/null 2>&1" % {kfile, kpattern})
- return stat == 0 and kfile
end
- for name, file in pairs(uploads) do
- local e = {name=name, func=function()
- local imgstream = ltn12.source.file(io.open(file))
- local kf = blocks[name].write ~= mtdow.WRITE_IMAGE
- and keepcfg and _kfile()
- return pcall(writer.write_block, writer,
- name, imgstream, kf)
- end}
-
- if blocks[name].system then
- flash[#flash+1] = e
- else
- table.insert(flash, 1, e)
- end
- end
-
- local reboot = {}
-
- luci.template.render("admin_system/upgrade", {blocks=blocks,
- flash=flash, keep_avail=keep_avail, reboot=reboot})
- if reboot.exec then
- local pid = posix.fork()
- if pid == 0 then
- posix.sleep(1)
- posix.exec("/tmp/reboot")
- end
- end
+ luci.http.prepare_content("text/html")
+ luci.template.render("admin_system/upgrade", {sysupgrade=plat, ret=ret, keep_avail=keep_avail})
+end
+
+function _keep_pattern()
+ local kpattern = ""
+ local files = luci.model.uci.cursor():get_all("luci", "flash_keep")
+ if files then
+ kpattern = ""
+ for k,v in pairs(files) do
+ kpattern = kpattern .. " " .. v
+ end
+ end
+ return kpattern
end
diff --git a/modules/admin-full/luasrc/view/admin_system/upgrade.htm b/modules/admin-full/luasrc/view/admin_system/upgrade.htm
index 8fe658a427..a3d97d6497 100644
--- a/modules/admin-full/luasrc/view/admin_system/upgrade.htm
+++ b/modules/admin-full/luasrc/view/admin_system/upgrade.htm
@@ -17,13 +17,12 @@ $Id$
<%:a_s_flash%>
<%:a_s_flash_upgrade1%>
-<% if next(blocks) and not next(flash) then %>
+<% if sysupgrade and not ret then %>
-<% elseif next(flash) then %>
+<% elseif ret then %>
<%:a_s_flash_received%>
+ <%:a_s_flash_inprogress%>
- <% reboot.exec = false
- for i, entry in ipairs(flash) do
- local name, func = entry.name, entry.func %>
- <%:a_s_flash_inprogress%> <%=name%>...
- <%=string.rep(" ", 32*1024)%>
- <%
- local stat, code = func()
- reboot.exec = reboot.exec or stat
- if stat and code then %>
- <%:ok%>
- <% else %>
- <%:a_s_flash_flasherr%>! (<%:code%> <%=code%>)
- <% end %>
- <% if reboot.exec then %>
-
- <%:a_s_flash_flashed%>
- <% end %>
+
+ <% %>
+ <% local ret = ret()
+ if ret == 0 then %>
+<%:a_s_flash_flashed%>
+ <% else %>
+<%:a_s_flash_flasherr%>! (<%:code%> <%=ret%>)
<% end %>
<% else %>
<%:a_s_flash_notimplemented%>
<% end %>
-<%+footer%>
\ No newline at end of file
+<%+footer%>
+<% if ret == 0 then luci.sys.reboot() end %>