Skip to content

Instantly share code, notes, and snippets.

@thomasjslone
Created February 12, 2025 21:16
Show Gist options
  • Save thomasjslone/0c6c74af32015ae32bee25baee976f9b to your computer and use it in GitHub Desktop.
Save thomasjslone/0c6c74af32015ae32bee25baee976f9b to your computer and use it in GitHub Desktop.
final version of dir image, redundant data handeling fixed
def image *args ## target, destination, strict
if args.length == 0 ; raise "Invalid arguemnts. Requires a target directory." ; end
if File.directory?(args[0].to_s) == false ; raise "Invalid target directory." ; else ; target = args[0].to_s ; end
if args.length > 1 ; if args[1].to_s == "" ; destination = Dir.getwd ; elsif File.directory?(args[1].to_s) ; destination = args[1].to_s ; else ; raise "Invalid arguemnts. No such destination directory." ; end ; end
strict = true ; if args.length > 2 and args[2] == false ; strict = false ; end
dirs = [] ; files = [] ; remaining = [target] ; cur = nil
loop do
if remaining.length == 0 ; break ; end
cur = remaining[0] ; remaining.delete_at(0)
begin ; cont = Dir.entries(cur) ; cont.delete(".") ; cont.delete("..") ; rescue ; if strict == true ; raise "Failed to map target directory." ; end ; next ; end
cont.each do |i| ; p = cur + "/" + i ; if File.file?(p) ; files << p ; elsif File.directory?(p) ; dirs << p ; remaining << p ; end ; end
end
if dirs.length == 0 and files.length == 0 ; raise "Error, target directory is empty." ; end
package = "" ; write_position = 0 ; dir_mappings = [] ; file_mappings = []
if dirs.length > 0
dirs.each do |d|
p = d.to_s.split(target)[-1] ; package << p ; i = p.length
dir_mappings << [write_position, write_position + (i - 1)]
write_position += i
end
end
if files.length > 0
files.each do |f| ; before_fail = f
begin ; fi = File.open(f, "rb") ; fc = fi.read ; fi.close ; rescue ; if strict == true ; raise "Failed to read file: " + f.to_s ; end ; next ; end
fp = f.split(target)[-1] ; fpl = fp.length - 1 ; fdl = (fpl) + (fc.length)
package << fp ; package << fc
file_mappings << [write_position, write_position + (fdl), fpl]
write_position += (fdl + 1)
end
end
index = target.split("/")[-1] + ":"
ddm = [] ; dir_mappings.each do |dm| ; ddm << dm.join("?") ; end ; index << ddm.join(";") + "*"
ffm = [] ; file_mappings.each do |fm| ; ffm << fm.join("?") ; end ; index << ffm.join(";")
package << "|" + index
if destination.to_s == "" ; path = Dir.getwd + "/" + target.split("/")[-1] + ".img" ; else ; path = destination.to_s + "/" + target.split("/")[-1] + ".img" ; end
begin ; f = File.open(path, "wb") ; f.write(package) ; f.close ; rescue ; raise "Failed to write file." ; end
return true
end
def build_image *args ## target, destination, strict
if args.length == 0 ; raise "Invalid arguments, requires a target file path." ; end
if File.file?(args[0].to_s) == false ; raise "No such target file." ; end ; target = args[0].to_s ;
if args[1].to_s == "" ; destination = Dir.getwd ; elsif File.directory?(args[1].to_s) ; destination = args[1].to_s ; else ; raise "Invalid arguemnts, no such destination directory." ; end
strict = true ; if args[2] == false ; strict = false ; end
begin ; f = File.open(target, "rb") ; package = f.read ; f.close ; rescue ; raise "Failed to read target file." ; end
package_size = package.length ; if package_size == 0 ; raise "ERROR: package may be corrupted. img file is empty." ; end
index = "" ; i = -1 ; failed = []
loop do
if package[i] == "|" ; break ; elsif package[i] == nil ; raise "ERROR: package may be corrupted. Index terminator was not found." ; end
index.insert(0,package[i]) ; i -= 1
end
if index.length == 0 ; raise "ERROR: package may be corrupted. Index is empty." ; end
if index.length >= package_size ; raise "ERROR: package may be corrupted. Image data not found." ; end
index_data = index.split(":")
dirname = index_data[0] ; mappings = index_data[1].split("*")
dir_mappings = mappings[0].split(";") ; file_mappings = mappings[1].split(";")
if File.directory?(destination + "/" + dirname) == true ; raise "ERROR target directory already exists." ; end
begin ; Dir.mkdir(destination + "/" + dirname) ; rescue ; raise "Failed to create target directory." ; end
dir_mappings.each do |dm|
range = dm.split("?") ; range[0] = range[0].to_i ; range[1] = range[1].to_i
path = destination + "/" + dirname + package[Range.new(range[0].to_i,range[1].to_i)]
begin ; Dir.mkdir(path)
rescue ; if strict == true ; raise "ERROR: Failed to create dir resource: " + path ; end ; failed << path
end
end
file_mappings.each do |fm|
range = fm.split("?") ; range[0] = range[0].to_i ; range[1] = range[1].to_i ; range[2] = range[2].to_i
path = destination + "/" + dirname + package[Range.new(range[0].to_i,(range[0].to_i + range[2].to_i))]
if failed.length > 0 ; if failed.include?(path.split("/")[0..-1].join("/")) ; next ; end ; end
begin ; f = File.open(path, "wb") ; f.write(package[Range.new(range[0]+(range[2]+1),range[1])]) ; f.close
rescue ; if strict == true ; raise "ERROR: Failed to create file resource: " + path ; end ; failed << path
end
end
if failed.length == 0 ; return true ; else ; return failed ; end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment