modules/admin-full: fix backup generation (#74)
authorJo-Philipp Wich <jow@openwrt.org>
Wed, 1 Jul 2009 14:17:59 +0000 (14:17 +0000)
committerJo-Philipp Wich <jow@openwrt.org>
Wed, 1 Jul 2009 14:17:59 +0000 (14:17 +0000)
modules/admin-full/luasrc/controller/admin/system.lua

index 56010ea9e62ea53c5c8824010ec5cd48eefb1ae1..1aabe637a19aad3c1ce286568d1808c011d7cfe3 100644 (file)
@@ -130,9 +130,9 @@ end
 
 function action_backup()
        local reset_avail = os.execute([[grep '"rootfs_data"' /proc/mtd >/dev/null 2>&1]]) == 0
-       local restore_cmd = "gunzip | tar -xC/ >/dev/null 2>&1"
-       local backup_cmd  = "tar -c %s | gzip 2>/dev/null"
-       
+       local restore_cmd = "tar -xzC/ >/dev/null 2>&1"
+       local backup_cmd  = "tar -cz %s 2>/dev/null"
+
        local restore_fpi 
        luci.http.setfilehandler(
                function(meta, chunk, eof)
@@ -156,12 +156,11 @@ function action_backup()
                luci.template.render("admin_system/applyreboot")
                luci.sys.reboot()
        elseif backup then
-               luci.util.perror(backup_cmd:format(_keep_pattern()))
-               local backup_fpi = io.popen(backup_cmd:format(_keep_pattern()), "r")
+               local reader = ltn12_popen(backup_cmd:format(_keep_pattern()))
                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(luci.ltn12.source.file(backup_fpi), luci.http.write)
+               luci.ltn12.pump.all(reader, luci.http.write)
        elseif reset then
                luci.template.render("admin_system/applyreboot")
                luci.util.exec("mtd -r erase rootfs_data")
@@ -341,3 +340,33 @@ function _keep_pattern()
        end
        return kpattern
 end
+
+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