118 lines
3.4 KiB
Ruby
118 lines
3.4 KiB
Ruby
|
#!/usr/bin/env ruby
|
||
|
|
||
|
=begin
|
||
|
|
||
|
Writes an XML-Tree for a cconfig directory
|
||
|
Idea by Nico Schottelius aka telmich
|
||
|
Implemented and (C) by René Nussbaumer aka KillerFox
|
||
|
|
||
|
This script is written for the clinux-System and published
|
||
|
under the terms of GPL 2.0
|
||
|
|
||
|
Version: 0.3
|
||
|
|
||
|
ChangeLog:
|
||
|
Version 0.3 (René Nussbaumer):
|
||
|
* Added support for binary files
|
||
|
* Added sha1 checksum for binary files
|
||
|
|
||
|
Version 0.2 (René Nussbaumer):
|
||
|
* Changed checking order: symlink, directory, file. Because of
|
||
|
a logical bug -> directory follows symlink so, when a symlink
|
||
|
points to a directory no «link» element is created.
|
||
|
|
||
|
Version 0.1 (René Nussbaumer):
|
||
|
* Holy hack for directory scanning (needs to be optimized)
|
||
|
* Hack for rexml to print out «lost» tags. This rexml sux.
|
||
|
|
||
|
Todo:
|
||
|
* Optimize scanning.
|
||
|
* Use another xml library instead of rexml crap.
|
||
|
Problem: Produce dependencies -> no std-lib
|
||
|
|
||
|
Features:
|
||
|
* Create a flat (no deepnes without directory) and 1:1 image
|
||
|
of an cconfig directory
|
||
|
|
||
|
=end
|
||
|
|
||
|
require 'rexml/document'
|
||
|
require 'base64'
|
||
|
require 'digest/sha1'
|
||
|
|
||
|
require 'filemagic'
|
||
|
|
||
|
@version = '0.3'
|
||
|
|
||
|
def determineTarget(entry)
|
||
|
return 'external' if(!File.expand_path(entry).index(@initpath))
|
||
|
return 'link' if(FileTest.symlink?(entry))
|
||
|
return 'object' if(FileTest.directory?(entry))
|
||
|
return 'attribute' if(FileTest.file?(entry))
|
||
|
return 'unknown' # Should never be reached
|
||
|
end
|
||
|
|
||
|
def createTree(dir, parent)
|
||
|
dir.each { |entry|
|
||
|
next if(entry =~ /^(\.|\.\.)$/)
|
||
|
|
||
|
if(FileTest.symlink?(entry))
|
||
|
e = parent.add_element('link')
|
||
|
|
||
|
# Much fun with links
|
||
|
e.add_attributes( { 'name' => entry, 'target' => determineTarget(File.readlink(entry)) } )
|
||
|
e.add_text(File.readlink(entry))
|
||
|
elsif(FileTest.directory?(entry))
|
||
|
e = parent.add_element('object')
|
||
|
e.add_attribute('name', entry)
|
||
|
|
||
|
# Bad, that we need to change the directory every time.
|
||
|
oldPwd = Dir.pwd
|
||
|
Dir.chdir(entry)
|
||
|
createTree(Dir.new('.'), e)
|
||
|
Dir.chdir(oldPwd)
|
||
|
elsif(FileTest.file?(entry))
|
||
|
e = parent.add_element('attribute')
|
||
|
e.add_attribute('name', entry)
|
||
|
if(File.stat(entry).size?)
|
||
|
# Yeah, we got one WITH content! W00h00, let's party.
|
||
|
|
||
|
fm = FileMagic.new(FileMagic::MAGIC_MIME)
|
||
|
if(fm.file(entry) =~ /executable/)
|
||
|
e.add_attribute('type', 'binary')
|
||
|
text = File.new(entry).read
|
||
|
e.add_attribute('sha1', Digest::SHA1.hexdigest(text))
|
||
|
e.add_text(Base64.encode64(text))
|
||
|
else
|
||
|
e.add_text(File.new(entry).read)
|
||
|
end
|
||
|
fm.close()
|
||
|
end
|
||
|
end
|
||
|
}
|
||
|
end
|
||
|
|
||
|
|
||
|
if(!ARGV[0] || !FileTest.directory?(ARGV[0]))
|
||
|
puts 'You need to specify a directory'
|
||
|
Kernel.exit(-1)
|
||
|
end
|
||
|
|
||
|
doc = REXML::Document.new
|
||
|
|
||
|
e = doc.add_element('cconfig')
|
||
|
e.add_attribute('name', File.basename(ARGV[0]))
|
||
|
e.add_attribute('version', @version)
|
||
|
|
||
|
@initpath = File.expand_path(ARGV[0])
|
||
|
Dir.chdir(ARGV[0])
|
||
|
createTree(Dir.new('.'), doc.root)
|
||
|
|
||
|
out = ''
|
||
|
doc.write(out, 0, false, true)
|
||
|
|
||
|
REXML::XMLDecl.new('1.0', 'utf-8').write($stdout) # This should automatically printed by rexml. Damn bugs.
|
||
|
puts ''
|
||
|
puts out # Workaround for a buggy rexml
|
||
|
|