Skip to content

Instantly share code, notes, and snippets.

@thomasjslone
Created February 12, 2025 18:28
Show Gist options
  • Save thomasjslone/4af5f49830ec91f435c583bfa9dacc88 to your computer and use it in GitHub Desktop.
Save thomasjslone/4af5f49830ec91f435c583bfa9dacc88 to your computer and use it in GitHub Desktop.
dir image backup before final edits
def image *args ## target, destination
if args.length == 0 ; raise "Invalid arguemnts. Requires a target directory." ; end
if File.directory?(args[0].to_s) == false ; raise "Invalid target directory." ; end
if args.length > 1 ; if args[1].to_s != "" and File.directory?(args[1]) == false ; raise "Invalid destination directory." ; end ; end
target = args[0].to_s ; destination = args[1].to_s
dirs = [] ; files = [] ; remaining = [target] ; cur = nil
begin
loop do
if remaining.length == 0 ; break ; end
cur = remaining[0] ; remaining.delete_at(0)
cont = Dir.entries(cur) ; cont.delete(".") ; cont.delete("..")
cont.each do |i|
p = cur + "/" + i
if File.file?(p) ; files << p ; elsif File.directory?(p) ; dirs << p ; remaining << p ; end
end
end
rescue ; raise "Failed to map target directory."
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
dir_mappings << [write_position, write_position + (p.length - 1)]
write_position += p.length
end
end
begin
before_fail = nil
if files.length > 0
files.each do |f| ; before_fail = f
fp = f.split(target)[-1] ; fi = File.open(f, "rb") ; fc = fi.read ; fi.close
fd = fp + fc ; package << fd
file_mappings << [write_position, write_position + (fd.length - 1), fp.length - 1]
write_position += fd.length
end
end
rescue ; raise "Failed to read file: " + before_fail
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 + "|" + package
if destination == "" ; 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
if args.length == 0 ; raise "Invalid arguments, requires a target file path." ; end
if File.file?(args[0].to_s) == false ; raise "No such file." ; end
if args.length > 1 ; if args[1].to_s != "" and File.directory?(args[1]) == false ; raise "Invalid destination directory." ; end ; end
target = args[0].to_s ; if args.to_s != "" ; destination = args[1].to_s ; else ; destination = Dir.getwd ; end
begin ; f = File.open(target, "rb") ; package = f.read ; f.close ; rescue ; raise "Failed to read target file." ; end
index = "" ; i = 0
loop do ; if package[i] == "|" ; break ; end ; index << package[i] ; i += 1 ; end
package_data = package[Range.new((i+1),-1)]
data = index.split(":")
dirname = data[0] ; mappings = data[1].split("*")
dir_mappings = mappings[0].split(";") ; file_mappings = mappings[1].split(";")
dir_paths = [] ; file_paths = [] ; file_contents = []
dir_mappings.each do |dm|
range = dm.split("?") ; range[0] = range[0].to_i ; range[1] = range[1].to_i
dir_paths << destination + "/" + dirname + package_data[Range.new(range[0].to_i,range[1].to_i)]
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
file_paths << destination + "/" + dirname + package_data[Range.new(range[0].to_i,(range[0].to_i + range[2].to_i))]
file_contents << package_data[Range.new((range[0]+(range[2]+1)),range[1])]
end
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
before_fail = nil ; dir_paths.each do |dp| ; begin ; before_fail = dp ; Dir.mkdir(dp) ; rescue ; raise "Failed to create directory: " + before_fail ; end ; end
i = 0 ; before_fail = nil
begin ; file_paths.each do |fp| ; f = File.open(fp, "wb") ; f.write(file_contents[i]) ; f.close ; i += 1 ; end
rescue ; raise "Failed to write file: " + before_fail.to_s
end
return true
end
@thomasjslone
Copy link
Author

image is fine but build_image is trash, this code should not be used on dirs containing more than 300kb

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment