[Ruby] Extractor de archivos [Código inside]

Iniciado por tbgio, 19 Julio 2011, 12:12 PM

0 Miembros y 1 Visitante están viendo este tema.

tbgio

Acabo de medio terminar un script para extraer archivos de un paquete BNDL en ruby. Aquí va el código para el que le pueda interesar:

# MEDP (Multi Extractor De Paquetes) 0.0.1
# Programado por SeCaProject
# 2011 en Ruby

# Librerias necesarias
require 'FileUtils'

# Pregunta qué archivo leer
puts "Nombre completo del archivo"
nombrearchivo = gets.strip
puts "Leyendo "+nombrearchivo+", un momento por favor..."
arch = File.new(nombrearchivo, "rb")
arch_leer = File.new(nombrearchivo, "rb")
# Saber que tipo de archivo es
tipo_arch = arch.read(4)
puts "Tipo de archivo: #{tipo_arch}"
arch.read(4)
dirhex1 = arch.sysread(1).unpack('H*')
dirhex2 = arch.sysread(1).unpack('H*')
dirhex3 = arch.sysread(1).unpack('H*')
dirhex4 = arch.sysread(1).unpack('H*')
dirtotal = [dirhex4,dirhex3,dirhex2,dirhex1].join.to_i(16)
puts "Longitud de la tabla: #{dirtotal}"
arch.read(4)
puts "Seguimos?"
seguimos = gets.strip

# Pone el archivo al principio
arch.seek(16, IO::SEEK_SET)

# Lee el archivo
cuenta0 = 16
for cuenta1 in 1..dirtotal do
if cuenta0 == dirtotal
break
end
cuenta0 = cuenta0 + 1
archivo1 = arch.read(1).bytes.first

# Si es una carpeta
if archivo1 == 1
cuenta0 = cuenta0 + 1
archivo1a = arch.read(1).bytes.first
# Me aseguro de que es una carpeta
if archivo1a == 1
# Lee el nombre del archivo, maximo 50 caracteres
for cuenta3 in 1..50 do
cuenta0 = cuenta0 + 1
archivo1b = arch.read(1).bytes.first
if archivo1b == 0
arch.seek(cuenta0-cuenta3, IO::SEEK_SET)
carpetanueva = arch.read(cuenta3)
break
end
end
end
# Si es un archivo
elsif archivo1 == 2
cuenta0 = cuenta0 + 12
# Distancia del inicio del archivo
dirhex1 = arch.sysread(1).unpack('H*')
dirhex2 = arch.sysread(1).unpack('H*')
dirhex3 = arch.sysread(1).unpack('H*')
dirhex4 = arch.sysread(1).unpack('H*')
ini_file = [dirhex4,dirhex3,dirhex2,dirhex1].join.to_i(16)
# 4 bloques vacios
arch.read(4)
# Longitud del archivo
dirhex1 = arch.sysread(1).unpack('H*')
dirhex2 = arch.sysread(1).unpack('H*')
dirhex3 = arch.sysread(1).unpack('H*')
dirhex4 = arch.sysread(1).unpack('H*')
end_file = [dirhex4,dirhex3,dirhex2,dirhex1].join.to_i(16)
# Lee el nombre del archivo
for cuenta3 in 1..100 do
cuenta0 = cuenta0 + 1
archivo2d = arch.read(1).bytes.first
if archivo2d == 0
# Copiando nombre al archivo
arch.seek(cuenta0-cuenta3, IO::SEEK_SET)
content = arch.read(cuenta3)
# Copiando contenido del archivo
arch_leer.seek(ini_file, IO::SEEK_SET)
content1 = arch_leer.read(end_file)
# Creando archivo
save_arch = File.open("#{tipo_arch}/#{content[1..-1].chop!}", File::CREAT | File::WRONLY | File::TRUNC)
save_arch.syswrite(content1)
break
end
end
end
end


De momento solo válido para archivos BNDL.
Como iba diciendo, después de medio terminarlo, me he preguntado a ver si este código se puede hacer más corto, o algo sobra, o lo que sea.
Eso por un lado, luego también querría saber cómo puedo hacer para que me lo meta en carpetas que el propio archivo tiene.
Para cualquier duda sobre el script, preguntad. Si algo no está claro también avisad.