#!/opt/Lua51/bin/lua -- Created by jiaqiang.ye@lnxall.com -- Pack a list of -- 2025/08/18 package.cpath = "/opt/Lua51/lib/lua/?.so;/opt/Lua51/lib/lua/loadall.so" package.path = "/opt/Lua51/share/lua/?.lua;/opt/Lua51/share/lua/?/init.lua;/opt/Lua51/lib/lua/?.lua;/opt/Lua51/lib/lua/?/init.lua" local invoker = require "invoker" local gfmt = string.format local g_MAXIPKS = 6 local g_TARBALL = "ALL-IPKS.tar.bz2" local g_INSTLIST = "ipkg-inst-list.sh" local g_OLDDIR = nil local g_FTOPDIR = nil local g_IPKGDIR = nil local g_PACKDIR = nil local g_ipklist = {} local g_ipkmap = {} local g_outfile = nil local function badstr(s) if type(s) ~= "string" then return true end if string.len(s) == 0 then return true end return false end local function ipkg_pack_init(arg0) local topdir = os.getenv("FTOPDIR") if badstr(topdir) then topdir = invoker.realpath(arg0) if not badstr(topdir) then topdir = string.match(topdir, "^(.+)/[^/]+$") if not badstr(topdir) then topdir = invoker.realpath(topdir .. "/../../..") end end if badstr(topdir) then io.stderr:write("Error, `FTOPDIR not defined.\n") io.stderr:flush() return false end io.stdout:write(gfmt("FTOPDIR found: %s\n", topdir)) io.stdout:flush() elseif invoker.statfile(topdir) ~= "directory" then io.stderr:write(gfmt("Error, directory not found: %s\n", topdir)) io.stderr:flush() return false end local instdir = os.getenv("FINSTALL_DIR") if badstr(instdir) then instdir = gfmt("%s/target/install", topdir) end g_PACKDIR = gfmt("%s/ipkg-pack", instdir) invoker.mkdir(g_PACKDIR) if invoker.statfile(g_PACKDIR) ~= "directory" then io.stderr:write(gfmt("Error, directory not found: %s\n", g_PACKDIR)) io.stderr:flush() return false end g_OLDDIR = invoker.getcwd() if badstr(g_OLDDIR) then io.stderr:write("Error, current work directory not found.\n") io.stderr:flush() return false end g_FTOPDIR, g_IPKGDIR = topdir, gfmt("%s/packages", instdir) if invoker.statfile(g_IPKGDIR) ~= "directory" then io.stderr:write(gfmt("Error, directory not found: %s\n", topdir)) io.stderr:flush() return false end return true end local function ipkg_pack_args() local arg1, idx = arg[1], 1 if badstr(arg1) then io.stderr:write("Error, output file not specified.\n") io.stderr:flush() return false end local pkgnum = 0 g_outfile = arg1 while true do idx = idx + 1 local argn, basen = arg[idx], nil if argn == nil then break end if badstr(argn) or not string.find(argn, "%.ipk$") then if type(argn) ~= "string" then argn = "" end io.stderr:write(gfmt("Error, invalid IPK file path: %s\n", argn)) io.stderr:flush() return false end basen = string.match(argn, "/([^/]+)$") if basen then local fullipk = gfmt("%s/%s", g_IPKGDIR, basen) if invoker.statfile(fullipk, true) ~= "regular" then io.stderr:write(gfmt("Error, IPK file not found in %s: %s\n", g_IPKGDIR, basen)) io.stderr:flush() return false end if g_ipkmap[basen] then io.stderr:write(gfmt("Warning: duplicated IPK file: %s, skipped.\n", basen)) io.stderr:flush() else pkgnum = pkgnum + 1 g_ipkmap[basen] = true g_ipklist[pkgnum] = basen io.stdout:write(gfmt("INFO: found IPK file, %d => %s ...\n", pkgnum, fullipk)) io.stdout:flush() if pkgnum > g_MAXIPKS then io.stderr:write(gfmt("Error, number of IPK files packed: %d\n", pkgnum)) io.stderr:flush() return false end end end end if pkgnum <= 1 then io.stderr:write(gfmt("Error, invalid number of IPK file: %d\n", pkgnum)) io.stderr:flush() return false end return true end local function ipkg_pack_file() if invoker.invoke(0, "/bin/sh", "-c", gfmt("cd '%s' && rm -rf -v *", g_PACKDIR)) ~= 0 then io.stderr:write(gfmt("Error, failed to remove existing files in %s\n", g_PACKDIR)) io.stderr:flush() return false end local ipkscript = gfmt("%s/scripts/dev-ipkg-install.sh", g_FTOPDIR) if invoker.statfile(ipkscript) ~= "regular" then io.stderr:write(gfmt("Error, file not found: %s\n", ipkscript)) io.stderr:flush() return false end if not invoker.chdir(g_IPKGDIR) then io.stderr:write(gfmt("Error, chdir(%s) has failed.\n", g_IPKGDIR)) io.stderr:flush() return false end local flist = gfmt("%s/%s", g_PACKDIR, g_INSTLIST) local finst = io.open(flist, "wb") if not finst then io.stderr:write(gfmt("Error, failed to open file: %s\n", flist)) io.stderr:flush() return false end finst:write("#!/bin/sh\n\n") local cmdtab = { [1] = "cp", [2] = "-v", [3] = "-f" } for _, fipk in ipairs(g_ipklist) do cmdtab[#cmdtab + 1] = fipk finst:write(gfmt("opkg_do_inst '%s'\n", fipk)) end finst:close(); finst = nil cmdtab[#cmdtab + 1] = gfmt("%s/", g_PACKDIR) if invoker.invoke(0, cmdtab) ~= 0 then io.stderr:write(gfmt("Error, command execution has failed:\n\t%s\n", table.concat(cmdtab, " "))) io.stderr:flush() return false end invoker.chdir(g_PACKDIR) if invoker.invoke(0, "sh", "-c", gfmt("tar -c -f - %s *.ipk | bzip2 -z -3 -c > %s", g_INSTLIST, g_TARBALL)) ~= 0 then io.stderr:write("Error, failed to compress all IPK files.\n") io.stderr:flush() return false end if invoker.invoke(0, "sh", "-c", gfmt("exec cat '%s' '%s' > OUTPUT", ipkscript, g_TARBALL)) ~= 0 then io.stderr:write("Error, failed to generate OUTPUT.\n") io.stderr:flush() return false end if invoker.chdir(g_OLDDIR) ~= 0 then io.stderr:write(gfmt("Error, chdir(%s) has failed.\n", g_OLDDIR)) io.stderr:flush() return false end return invoker.invoke(0, "mv", "-v", "-f", gfmt("%s/OUTPUT", g_PACKDIR), g_outfile) == 0 end if not ipkg_pack_init(arg[0]) then os.exit(1) end if not ipkg_pack_args() then os.exit(2) end if not ipkg_pack_file() then os.exit(3) end os.exit(0)