This commit is contained in:
Ward Wouts 2008-10-01 13:04:33 +00:00
parent d9fbba0c0b
commit 6061f7e14e

View file

@ -4,7 +4,7 @@
# $URL$ # $URL$
# #
# Copyright (c) 2007 Ward Wouts <ward@wouts.nl> # Copyright (c) 2007, 2008 Ward Wouts <ward@wouts.nl>
# #
# Permission to use, copy, modify, and distribute this software for any # Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above # purpose with or without fee is hereby granted, provided that the above
@ -25,11 +25,107 @@ require 'rexml/document'
require 'date' require 'date'
require 'getoptlong' require 'getoptlong'
class DSParse
# info over DS_Store files is te vinden op https://wiki.mozilla.org/DS_Store_File_Format
# iemand heeft ooit ook een 'dsdump.c' programma geschreven wat wel wat info bevat
def initialize
@store = Array.new
end
def arr2long(arr)
return (arr[0]<<24) + (arr[1]<<16) + (arr[2]<<8) + arr[3]
end
def arr2string(arr)
string = ""
(0...arr.length).step(2){|i|
string += ((arr[i]<<8) + (arr[i+1])).chr
}
return string
end
def readfile(filename)
@store = Array.new
File.open(filename).each_byte{|byte|
@store.push byte
}
end
def readstring(string)
@store = Array.new
string.each_byte{|byte|
@store.push byte
}
end
def isds?
# 00 00 00 01 42 75 64 31
# kan vast netter, don't care
@store[0] == 0x00 && @store[1] == 0x00 && @store[2] == 0x00 && @store[3] == 0x01 &&
@store[4] == 0x42 && @store[5] == 0x75 && @store[6] == 0x64 && @store[7] == 0x31
end
def getfilenames
filenames = Array.new
counter = 0
offset = arr2long(@store[0x14, 4])
offset &= ~15 # tim zegt dat dit de laatste zoveel bits op 0 zet.
structcount = arr2long(@store[offset+8, 4])
pointer = offset+12
(0...structcount).each{|structcounter|
objnamelength = arr2long(@store[pointer, 4])
pointer+=4
objnamebuf = @store[pointer, objnamelength*2]
pointer+=objnamelength*2
filenames.push arr2string(objnamebuf)
objtag = @store[pointer, 4].map{|x| x.chr}.join('')
pointer+=4
objtype = @store[pointer, 4].map{|x| x.chr}.join('')
pointer+=4
datasize = 0
case objtype
when 'bool'
datasize = 1
when 'shor', 'long', 'type'
datasize = 4
when 'ustr'
datasize = arr2long(@store[pointer, 4])
pointer += 4
datasize *= 2
when 'blob'
datasize = arr2long(@store[pointer, 4])
pointer += 4
else
puts "Unrecognized data type"
end
if datasize > 0
data = @store[pointer, datasize]
pointer += datasize
end
}
filenames.uniq!
return filenames
end
end # class DSParse
def usage def usage
puts <<EOT puts <<EOT
Usage: #{$0.sub(/.*\//, "")} [options] -u <baseurl> Usage: #{$0.sub(/.*\//, "")} [options] -u <baseurl>
-h, --help show this message -h, --help show this message
-m <svn|cvs|ds> check for one of subversion, CVS or .DS_Store (default: all)
-u <baseurl> set baseurl -u <baseurl> set baseurl
-s use ssl -s use ssl
EOT EOT
@ -41,6 +137,7 @@ def cmdline
begin begin
opts = GetoptLong.new( opts = GetoptLong.new(
[ "-h", "--help", GetoptLong::NO_ARGUMENT ], [ "-h", "--help", GetoptLong::NO_ARGUMENT ],
[ "-m", GetoptLong::REQUIRED_ARGUMENT ],
[ "-u", GetoptLong::REQUIRED_ARGUMENT ], [ "-u", GetoptLong::REQUIRED_ARGUMENT ],
[ "-s", GetoptLong::NO_ARGUMENT ] [ "-s", GetoptLong::NO_ARGUMENT ]
) )
@ -84,11 +181,11 @@ def fetch(uri_str, limit = 10)
when Net::HTTPUnauthorized then puts "401 Authorization Required #{uri_str}" when Net::HTTPUnauthorized then puts "401 Authorization Required #{uri_str}"
when Net::HTTPUnauthorized then puts "401 Authorization Required #{uri_str}" when Net::HTTPUnauthorized then puts "401 Authorization Required #{uri_str}"
when Net::HTTPForbidden then puts "403 Forbidden #{uri_str}" when Net::HTTPForbidden then puts "403 Forbidden #{uri_str}"
when Net::HTTPNotFound then puts "404 Not Found #{uri_str}" i# when Net::HTTPNotFound then puts "404 Not Found #{uri_str}"
else else
response.error! response.error!
end end
end end
def svnparse(url) def svnparse(url)
puts "\n#{url}" puts "\n#{url}"
@ -100,7 +197,8 @@ def svnparse(url)
return return
end end
dirs = Array.new dirs = Array.new
if body[0].chr == '<' case body[0].chr
when '<'
xmldoc = REXML::Document.new(body) xmldoc = REXML::Document.new(body)
xmldoc.elements.each("wc-entries/entry") {|item| xmldoc.elements.each("wc-entries/entry") {|item|
case item.attribute("kind").to_s case item.attribute("kind").to_s
@ -116,7 +214,7 @@ def svnparse(url)
puts " Strange kind #{item.attribute("kind")}" puts " Strange kind #{item.attribute("kind")}"
end end
} }
else when '8'
lastline = "" lastline = ""
commitdate = "" commitdate = ""
author = "" author = ""
@ -144,6 +242,8 @@ def svnparse(url)
lastline = line lastline = line
end end
} }
else
$stderr.puts "Unknown SVN entries format found."
end end
dirs.each{|dir| dirs.each{|dir|
#p "#{url}/#{dir}" #p "#{url}/#{dir}"
@ -176,9 +276,81 @@ def cvsparse(url)
} }
end end
def dsparse(url)
puts "\n#{url}"
ds = DSParse.new
dirs = Array.new
begin
body = fetch("#{url}/.DS_Store").body
rescue
end
if body.nil?
return
end
ds.readstring(body)
if ! ds.isds?
$stderr.puts "Not a .DS_Store format file"
return
end
entries = ds.getfilenames
(0...entries.length).each{|x|
begin
if entries[x] == '.' or entries[x] == '..'
next
end
body = fetch("#{url}/#{entries[x]}/.DS_Store").body
dscheck = DSParse.new
dscheck.readstring(body)
if dscheck.isds?
dirs.push entries[x]
entries[x] = "#{entries[x]}/"
end
rescue
end
}
puts entries
dirs.each{|dir|
dsparse("#{url}/#{dir}")
}
end
def checksvn(url)
begin
puts "==================================================="
body = fetch("#{url}/.svn/entries").body
puts "Subversion info found:"
svnparse(url)
rescue
end
end
def checkcvs(url)
begin
puts "==================================================="
body = fetch("#{url}/CVS/Entries").body
puts "CVS info found:"
cvsparse(url)
rescue
end
end
def checkds(url)
begin
puts "==================================================="
body = fetch("#{url}/.DS_Store").body
puts ".DS_Store file found:"
dsparse(url)
rescue
end
end
options = cmdline options = cmdline
if options["-u"].nil? if options["-u"].nil?
usage usage
else
if ! options["-u"].match(/^http/)
options["-u"] = "http://#{options["-u"]}"
end
end end
if options["-s"] if options["-s"]
@ -187,31 +359,17 @@ else
@use_ssl = false @use_ssl = false
end end
mode=nil if options["-m"].nil?
checksvn(options["-u"])
# first test for subversion entries checkcvs(options["-u"])
if mode.nil? checkds(options["-u"])
begin
body = fetch("#{options["-u"]}/.svn/entries").body
mode="subversion"
rescue
end
end
# then test for CVS entries
if mode.nil?
begin
body = fetch("#{options["-u"]}/CVS/Entries").body
mode="cvs"
rescue
end
end
if mode.nil?
puts "Couldn't determine versioning information"
else else
case mode case options["-m"]
when "subversion" then svnparse(options["-u"]) when "svn"
when "cvs" then cvsparse(options["-u"]) checksvn(options["-u"])
when "cvs"
checkcvs(options["-u"])
when "ds"
checkds(options["-u"])
end end
end end