| 
									
										
										
										
											2002-07-26 22:12:34 +08:00
										 |  |  | #!/usr/bin/env ruby | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-21 21:54:32 +08:00
										 |  |  | require 'zip/zip' | 
					
						
							| 
									
										
										
										
											2002-07-27 04:58:51 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-07-27 06:20:25 +08:00
										 |  |  | module Zip | 
					
						
							| 
									
										
										
										
											2002-09-12 03:28:32 +08:00
										 |  |  |   module ZipFileSystem | 
					
						
							| 
									
										
										
										
											2003-08-20 22:10:20 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def initialize | 
					
						
							| 
									
										
										
										
											2003-08-20 23:30:03 +08:00
										 |  |  |       mappedZip = ZipFileNameMapper.new(self) | 
					
						
							|  |  |  |       @zipFsDir  = ZipFsDir.new(mappedZip) | 
					
						
							|  |  |  |       @zipFsFile = ZipFsFile.new(mappedZip) | 
					
						
							| 
									
										
										
										
											2003-08-20 22:10:20 +08:00
										 |  |  |       @zipFsDir.file = @zipFsFile | 
					
						
							|  |  |  |       @zipFsFile.dir = @zipFsDir | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-07-27 06:20:25 +08:00
										 |  |  |     def dir | 
					
						
							| 
									
										
										
										
											2003-08-20 22:10:20 +08:00
										 |  |  |       @zipFsDir | 
					
						
							| 
									
										
										
										
											2002-07-27 06:20:25 +08:00
										 |  |  |     end | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     def file | 
					
						
							| 
									
										
										
										
											2003-08-20 22:10:20 +08:00
										 |  |  |       @zipFsFile | 
					
						
							| 
									
										
										
										
											2002-07-27 06:20:25 +08:00
										 |  |  |     end | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     class ZipFsFile | 
					
						
							| 
									
										
										
										
											2003-08-13 16:39:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-20 22:10:20 +08:00
										 |  |  |       attr_writer :dir | 
					
						
							|  |  |  | #      protected :dir | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-13 16:39:01 +08:00
										 |  |  |       class ZipFsStat | 
					
						
							|  |  |  |         def initialize(zipFsFile, entryName) | 
					
						
							|  |  |  |           @zipFsFile = zipFsFile | 
					
						
							|  |  |  |           @entryName = entryName | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2003-08-13 17:29:42 +08:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2003-08-13 22:29:53 +08:00
										 |  |  |         def forward_invoke(msg) | 
					
						
							| 
									
										
										
										
											2003-08-13 17:29:42 +08:00
										 |  |  |           @zipFsFile.send(msg, @entryName) | 
					
						
							| 
									
										
										
										
											2003-08-13 16:39:01 +08:00
										 |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-13 21:18:25 +08:00
										 |  |  |         def kind_of?(t) | 
					
						
							| 
									
										
										
										
											2003-08-18 00:28:18 +08:00
										 |  |  |           super || t == ::File::Stat  | 
					
						
							| 
									
										
										
										
											2003-08-13 21:18:25 +08:00
										 |  |  |         end | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2003-08-13 22:29:53 +08:00
										 |  |  |         forward_message :forward_invoke, :file?, :directory?, :pipe?, :chardev? | 
					
						
							|  |  |  |         forward_message :forward_invoke, :symlink?, :socket?, :blockdev? | 
					
						
							|  |  |  |         forward_message :forward_invoke, :readable?, :readable_real? | 
					
						
							|  |  |  |         forward_message :forward_invoke, :writable?, :writable_real? | 
					
						
							|  |  |  |         forward_message :forward_invoke, :executable?, :executable_real? | 
					
						
							|  |  |  |         forward_message :forward_invoke, :sticky?, :owned?, :grpowned? | 
					
						
							|  |  |  |         forward_message :forward_invoke, :setuid?, :setgid? | 
					
						
							|  |  |  |         forward_message :forward_invoke, :zero? | 
					
						
							|  |  |  |         forward_message :forward_invoke, :size, :size? | 
					
						
							| 
									
										
										
										
											2003-08-14 11:40:49 +08:00
										 |  |  |         forward_message :forward_invoke, :mtime, :atime, :ctime | 
					
						
							| 
									
										
										
										
											2003-08-13 21:18:25 +08:00
										 |  |  |          | 
					
						
							|  |  |  |         def blocks; nil; end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-30 23:07:56 +08:00
										 |  |  |         def get_entry | 
					
						
							|  |  |  |           @zipFsFile.__send__(:get_entry, @entryName) | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |         private :get_entry | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def gid | 
					
						
							|  |  |  |           e = get_entry | 
					
						
							|  |  |  |           if e.extra.member? "IUnix" | 
					
						
							|  |  |  |             e.extra["IUnix"].gid || 0
 | 
					
						
							|  |  |  |           else | 
					
						
							|  |  |  |             0
 | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2003-08-13 21:18:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-30 23:07:56 +08:00
										 |  |  |         def uid | 
					
						
							|  |  |  |           e = get_entry | 
					
						
							|  |  |  |           if e.extra.member? "IUnix" | 
					
						
							|  |  |  |             e.extra["IUnix"].uid || 0
 | 
					
						
							|  |  |  |           else | 
					
						
							|  |  |  |             0
 | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2003-08-13 21:18:25 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         def ino; 0; end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def dev; 0; end | 
					
						
							| 
									
										
										
										
											2003-08-13 16:39:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-13 21:18:25 +08:00
										 |  |  |         def rdev; 0; end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def rdev_major; 0; end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def rdev_minor; 0; end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def ftype | 
					
						
							|  |  |  |           if file? | 
					
						
							|  |  |  |             return "file" | 
					
						
							|  |  |  |           elsif directory? | 
					
						
							|  |  |  |             return "directory" | 
					
						
							|  |  |  |           else | 
					
						
							|  |  |  |             raise StandardError, "Unknown file type" | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def nlink; 1; end | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         def blksize; nil; end | 
					
						
							| 
									
										
										
										
											2003-08-19 20:33:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-30 23:07:56 +08:00
										 |  |  |         def mode | 
					
						
							|  |  |  |           e = get_entry | 
					
						
							|  |  |  |           if e.fstype == 3
 | 
					
						
							|  |  |  |             e.externalFileAttributes >> 16
 | 
					
						
							|  |  |  |           else | 
					
						
							|  |  |  |             33206 # 33206 is equivalent to -rw-rw-rw- | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2003-08-13 16:39:01 +08:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-20 23:30:03 +08:00
										 |  |  |       def initialize(mappedZip) | 
					
						
							|  |  |  | 	@mappedZip = mappedZip | 
					
						
							| 
									
										
										
										
											2002-07-27 06:20:25 +08:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2004-01-30 23:07:56 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       def get_entry(fileName) | 
					
						
							|  |  |  |         if ! exists?(fileName) | 
					
						
							|  |  |  |           raise Errno::ENOENT, "No such file or directory - #{fileName}" | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |         @mappedZip.find_entry(fileName) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |       private :get_entry | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def unix_mode_cmp(fileName, mode) | 
					
						
							|  |  |  |         begin | 
					
						
							|  |  |  |           e = get_entry(fileName) | 
					
						
							|  |  |  |           e.fstype == 3 && ((e.externalFileAttributes >> 16) & mode ) != 0
 | 
					
						
							|  |  |  |         rescue Errno::ENOENT | 
					
						
							|  |  |  |           false | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |       private :unix_mode_cmp | 
					
						
							| 
									
										
										
										
											2002-07-27 06:20:25 +08:00
										 |  |  |        | 
					
						
							|  |  |  |       def exists?(fileName) | 
					
						
							| 
									
										
										
										
											2003-08-20 23:30:03 +08:00
										 |  |  |         expand_path(fileName) == "/" || @mappedZip.find_entry(fileName) != nil | 
					
						
							| 
									
										
										
										
											2002-07-27 06:20:25 +08:00
										 |  |  |       end | 
					
						
							|  |  |  |       alias :exist? :exists? | 
					
						
							|  |  |  |        | 
					
						
							| 
									
										
										
										
											2003-08-13 15:51:42 +08:00
										 |  |  |       # Permissions not implemented, so if the file exists it is accessible | 
					
						
							| 
									
										
										
										
											2003-08-13 17:44:47 +08:00
										 |  |  |       alias owned?           exists? | 
					
						
							|  |  |  |       alias grpowned?        exists? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-30 23:07:56 +08:00
										 |  |  |       def readable?(fileName) | 
					
						
							|  |  |  |         unix_mode_cmp(fileName, 0444) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |       alias readable_real?   readable? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def writable?(fileName) | 
					
						
							|  |  |  |         unix_mode_cmp(fileName, 0222) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |       alias writable_real?   writable? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def executable?(fileName) | 
					
						
							|  |  |  |         unix_mode_cmp(fileName, 0111) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |       alias executable_real? executable? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-13 17:44:47 +08:00
										 |  |  |       def setuid?(fileName) | 
					
						
							| 
									
										
										
										
											2004-01-30 23:07:56 +08:00
										 |  |  |         unix_mode_cmp(fileName, 04000) | 
					
						
							| 
									
										
										
										
											2003-08-13 17:44:47 +08:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def setgid?(fileName) | 
					
						
							| 
									
										
										
										
											2004-01-30 23:07:56 +08:00
										 |  |  |         unix_mode_cmp(fileName, 02000) | 
					
						
							| 
									
										
										
										
											2003-08-13 17:44:47 +08:00
										 |  |  |       end | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |       def sticky?(fileName) | 
					
						
							| 
									
										
										
										
											2004-01-30 23:07:56 +08:00
										 |  |  |         unix_mode_cmp(fileName, 01000) | 
					
						
							| 
									
										
										
										
											2003-08-13 17:44:47 +08:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2003-08-13 15:51:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-13 21:18:25 +08:00
										 |  |  |       def umask(*args) | 
					
						
							| 
									
										
										
										
											2003-08-18 00:28:18 +08:00
										 |  |  |         ::File.umask(*args) | 
					
						
							| 
									
										
										
										
											2003-08-13 21:18:25 +08:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def truncate(fileName, len) | 
					
						
							|  |  |  |         raise StandardError, "truncate not supported" | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-07-27 06:20:25 +08:00
										 |  |  |       def directory?(fileName) | 
					
						
							| 
									
										
										
										
											2003-08-20 23:30:03 +08:00
										 |  |  | 	entry = @mappedZip.find_entry(fileName) | 
					
						
							| 
									
										
										
										
											2003-08-20 21:39:56 +08:00
										 |  |  | 	expand_path(fileName) == "/" || (entry != nil && entry.directory?) | 
					
						
							| 
									
										
										
										
											2002-07-27 06:20:25 +08:00
										 |  |  |       end | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |       def open(fileName, openMode = "r", &block) | 
					
						
							| 
									
										
										
										
											2003-08-19 00:39:50 +08:00
										 |  |  |         case openMode | 
					
						
							|  |  |  |         when "r"  | 
					
						
							| 
									
										
										
										
											2003-08-20 23:30:03 +08:00
										 |  |  |           @mappedZip.get_input_stream(fileName, &block) | 
					
						
							| 
									
										
										
										
											2003-08-19 00:39:50 +08:00
										 |  |  |         when "w" | 
					
						
							| 
									
										
										
										
											2003-08-20 23:30:03 +08:00
										 |  |  |           @mappedZip.get_output_stream(fileName, &block) | 
					
						
							| 
									
										
										
										
											2003-08-19 00:39:50 +08:00
										 |  |  |         else | 
					
						
							|  |  |  |           raise StandardError, "openmode '#{openMode} not supported" unless openMode == "r" | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2002-07-27 06:20:25 +08:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2002-07-27 21:25:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       def new(fileName, openMode = "r") | 
					
						
							|  |  |  | 	open(fileName, openMode) | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2002-07-27 06:20:25 +08:00
										 |  |  |        | 
					
						
							|  |  |  |       def size(fileName) | 
					
						
							| 
									
										
										
										
											2003-08-20 23:30:03 +08:00
										 |  |  | 	@mappedZip.get_entry(fileName).size | 
					
						
							| 
									
										
										
										
											2002-07-27 06:20:25 +08:00
										 |  |  |       end | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |       # nil for not found and nil for directories | 
					
						
							|  |  |  |       def size?(fileName) | 
					
						
							| 
									
										
										
										
											2003-08-20 23:30:03 +08:00
										 |  |  | 	entry = @mappedZip.find_entry(fileName) | 
					
						
							| 
									
										
										
										
											2002-07-27 06:20:25 +08:00
										 |  |  | 	return (entry == nil || entry.directory?) ? nil : entry.size | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |        | 
					
						
							| 
									
										
										
										
											2004-01-30 23:07:56 +08:00
										 |  |  |       def chown(ownerInt, groupInt, *filenames) | 
					
						
							|  |  |  |         filenames.each { |fileName| | 
					
						
							|  |  |  |           e = get_entry(fileName) | 
					
						
							|  |  |  |           unless e.extra.member?("IUnix") | 
					
						
							|  |  |  |             e.extra.create("IUnix") | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |           e.extra["IUnix"].uid = ownerInt | 
					
						
							|  |  |  |           e.extra["IUnix"].gid = groupInt | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2003-08-13 21:18:25 +08:00
										 |  |  |         filenames.size | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def chmod (modeInt, *filenames) | 
					
						
							| 
									
										
										
										
											2004-01-30 23:07:56 +08:00
										 |  |  |         filenames.each { |fileName| | 
					
						
							|  |  |  |           e = get_entry(fileName) | 
					
						
							|  |  |  |           e.fstype = 3 # force convertion filesystem type to unix | 
					
						
							|  |  |  |           e.externalFileAttributes = modeInt << 16
 | 
					
						
							| 
									
										
										
										
											2003-08-13 21:18:25 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |         filenames.size | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-07-27 06:20:25 +08:00
										 |  |  |       def zero?(fileName) | 
					
						
							|  |  |  | 	sz = size(fileName) | 
					
						
							|  |  |  | 	sz == nil || sz == 0
 | 
					
						
							|  |  |  |       rescue Errno::ENOENT | 
					
						
							|  |  |  | 	false | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |       def file?(fileName) | 
					
						
							| 
									
										
										
										
											2003-08-20 23:30:03 +08:00
										 |  |  | 	entry = @mappedZip.find_entry(fileName) | 
					
						
							| 
									
										
										
										
											2002-07-27 06:20:25 +08:00
										 |  |  | 	entry != nil && entry.file? | 
					
						
							|  |  |  |       end       | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |       def dirname(fileName) | 
					
						
							|  |  |  | 	::File.dirname(fileName) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |       def basename(fileName) | 
					
						
							|  |  |  | 	::File.basename(fileName) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |       def split(fileName) | 
					
						
							|  |  |  | 	::File.split(fileName) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |       def join(*fragments) | 
					
						
							|  |  |  | 	::File.join(*fragments) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |        | 
					
						
							| 
									
										
										
										
											2004-01-30 23:07:56 +08:00
										 |  |  |       def utime(modifiedTime, *fileNames) | 
					
						
							|  |  |  |         fileNames.each { |fileName| | 
					
						
							|  |  |  |           get_entry(fileName).time = modifiedTime | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2003-08-14 11:40:49 +08:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-07-27 06:20:25 +08:00
										 |  |  |       def mtime(fileName) | 
					
						
							| 
									
										
										
										
											2003-08-20 23:30:03 +08:00
										 |  |  | 	@mappedZip.get_entry(fileName).mtime | 
					
						
							| 
									
										
										
										
											2002-07-27 06:20:25 +08:00
										 |  |  |       end | 
					
						
							|  |  |  |        | 
					
						
							| 
									
										
										
										
											2003-08-14 11:40:49 +08:00
										 |  |  |       def atime(fileName) | 
					
						
							| 
									
										
										
										
											2004-01-30 23:07:56 +08:00
										 |  |  |         e = get_entry(fileName) | 
					
						
							|  |  |  |         if e.extra.member? "UniversalTime" | 
					
						
							|  |  |  |           e.extra["UniversalTime"].atime | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           nil | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2003-08-14 11:40:49 +08:00
										 |  |  |       end | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |       def ctime(fileName) | 
					
						
							| 
									
										
										
										
											2004-01-30 23:07:56 +08:00
										 |  |  |         e = get_entry(fileName) | 
					
						
							|  |  |  |         if e.extra.member? "UniversalTime" | 
					
						
							|  |  |  |           e.extra["UniversalTime"].ctime | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           nil | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2003-08-14 11:40:49 +08:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-07-27 06:20:25 +08:00
										 |  |  |       def pipe?(filename) | 
					
						
							|  |  |  | 	false | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |       def blockdev?(filename) | 
					
						
							|  |  |  | 	false | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |        | 
					
						
							| 
									
										
										
										
											2002-09-12 04:18:24 +08:00
										 |  |  |       def chardev?(filename) | 
					
						
							|  |  |  | 	false | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |        | 
					
						
							| 
									
										
										
										
											2002-07-27 06:20:25 +08:00
										 |  |  |       def symlink?(fileName) | 
					
						
							|  |  |  | 	false | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |       def socket?(fileName) | 
					
						
							|  |  |  | 	false | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |       def ftype(fileName) | 
					
						
							| 
									
										
										
										
											2003-08-20 23:30:03 +08:00
										 |  |  | 	@mappedZip.get_entry(fileName).directory? ? "directory" : "file" | 
					
						
							| 
									
										
										
										
											2002-07-27 06:20:25 +08:00
										 |  |  |       end | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |       def readlink(fileName) | 
					
						
							| 
									
										
										
										
											2003-08-21 00:08:07 +08:00
										 |  |  | 	raise NotImplementedError, "The readlink() function is not implemented" | 
					
						
							| 
									
										
										
										
											2002-07-27 06:20:25 +08:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2002-07-27 06:23:32 +08:00
										 |  |  |        | 
					
						
							|  |  |  |       def symlink(fileName, symlinkName) | 
					
						
							| 
									
										
										
										
											2003-08-21 00:08:07 +08:00
										 |  |  | 	raise NotImplementedError, "The symlink() function is not implemented" | 
					
						
							| 
									
										
										
										
											2002-07-27 06:23:32 +08:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2002-07-27 06:25:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       def link(fileName, symlinkName) | 
					
						
							| 
									
										
										
										
											2003-08-21 00:08:07 +08:00
										 |  |  | 	raise NotImplementedError, "The link() function is not implemented" | 
					
						
							| 
									
										
										
										
											2002-07-27 06:25:36 +08:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2002-07-27 06:30:04 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       def pipe | 
					
						
							| 
									
										
										
										
											2003-08-21 00:08:07 +08:00
										 |  |  | 	raise NotImplementedError, "The pipe() function is not implemented" | 
					
						
							| 
									
										
										
										
											2002-07-27 06:30:04 +08:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2002-09-12 04:18:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-13 16:39:01 +08:00
										 |  |  |       def stat(fileName) | 
					
						
							| 
									
										
										
										
											2003-08-13 21:18:25 +08:00
										 |  |  |         if ! exists?(fileName) | 
					
						
							| 
									
										
										
										
											2003-08-20 21:39:56 +08:00
										 |  |  |           raise Errno::ENOENT, fileName | 
					
						
							| 
									
										
										
										
											2003-08-13 21:18:25 +08:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2003-08-13 16:39:01 +08:00
										 |  |  |         ZipFsStat.new(self, fileName) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-13 21:18:25 +08:00
										 |  |  |       alias lstat stat | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-09-12 04:18:24 +08:00
										 |  |  |       def readlines(fileName) | 
					
						
							|  |  |  | 	open(fileName) { |is| is.readlines } | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-18 00:28:18 +08:00
										 |  |  |       def read(fileName) | 
					
						
							| 
									
										
										
										
											2003-08-20 23:30:03 +08:00
										 |  |  |         @mappedZip.read(fileName) | 
					
						
							| 
									
										
										
										
											2003-08-18 00:28:18 +08:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-09-12 04:18:24 +08:00
										 |  |  |       def popen(*args, &aProc) | 
					
						
							|  |  |  | 	File.popen(*args, &aProc) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def foreach(fileName, aSep = $/, &aProc) | 
					
						
							|  |  |  | 	open(fileName) { |is| is.each_line(aSep, &aProc) } | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2002-09-12 06:10:34 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       def delete(*args) | 
					
						
							|  |  |  | 	args.each {  | 
					
						
							|  |  |  | 	  |fileName| | 
					
						
							|  |  |  | 	  if directory?(fileName) | 
					
						
							|  |  |  | 	    raise Errno::EISDIR, "Is a directory - \"#{fileName}\"" | 
					
						
							|  |  |  | 	  end | 
					
						
							| 
									
										
										
										
											2003-08-20 23:30:03 +08:00
										 |  |  | 	  @mappedZip.remove(fileName)  | 
					
						
							| 
									
										
										
										
											2002-09-12 06:10:34 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-13 21:18:25 +08:00
										 |  |  |       def rename(fileToRename, newName) | 
					
						
							| 
									
										
										
										
											2003-08-20 23:30:03 +08:00
										 |  |  |         @mappedZip.rename(fileToRename, newName) { true } | 
					
						
							| 
									
										
										
										
											2003-08-13 21:18:25 +08:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-09-12 06:10:34 +08:00
										 |  |  |       alias :unlink :delete | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-20 21:39:56 +08:00
										 |  |  |       def expand_path(aPath) | 
					
						
							| 
									
										
										
										
											2003-08-20 23:30:03 +08:00
										 |  |  |         @mappedZip.expand_path(aPath) | 
					
						
							| 
									
										
										
										
											2003-08-20 21:39:56 +08:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2002-07-27 05:32:12 +08:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2003-08-20 21:39:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-20 22:10:20 +08:00
										 |  |  |     class ZipFsDir | 
					
						
							|  |  |  |        | 
					
						
							| 
									
										
										
										
											2003-08-20 23:30:03 +08:00
										 |  |  |       def initialize(mappedZip) | 
					
						
							|  |  |  |         @mappedZip = mappedZip | 
					
						
							| 
									
										
										
										
											2003-08-20 21:39:56 +08:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2003-08-20 22:10:20 +08:00
										 |  |  |        | 
					
						
							|  |  |  |       attr_writer :file | 
					
						
							| 
									
										
										
										
											2003-08-21 20:32:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       def new(aDirectoryName) | 
					
						
							|  |  |  |         ZipFsDirIterator.new(entries(aDirectoryName)) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def open(aDirectoryName) | 
					
						
							|  |  |  |         dirIt = new(aDirectoryName) | 
					
						
							|  |  |  |         if block_given? | 
					
						
							|  |  |  |           begin | 
					
						
							|  |  |  |             yield(dirIt) | 
					
						
							|  |  |  |             return nil | 
					
						
							|  |  |  |           ensure | 
					
						
							|  |  |  |             dirIt.close | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |         dirIt | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-20 23:30:03 +08:00
										 |  |  |       def pwd; @mappedZip.pwd; end | 
					
						
							| 
									
										
										
										
											2003-08-20 22:10:20 +08:00
										 |  |  |       alias getwd pwd | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |       def chdir(aDirectoryName) | 
					
						
							|  |  |  |         unless @file.stat(aDirectoryName).directory? | 
					
						
							|  |  |  |           raise Errno::EINVAL, "Invalid argument - #{aDirectoryName}" | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2003-08-20 23:30:03 +08:00
										 |  |  |         @mappedZip.pwd = @file.expand_path(aDirectoryName) | 
					
						
							| 
									
										
										
										
											2003-08-20 21:39:56 +08:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2003-08-20 22:10:20 +08:00
										 |  |  |        | 
					
						
							|  |  |  |       def entries(aDirectoryName) | 
					
						
							| 
									
										
										
										
											2003-08-21 04:44:12 +08:00
										 |  |  |         entries = [] | 
					
						
							|  |  |  |         foreach(aDirectoryName) { |e| entries << e } | 
					
						
							|  |  |  |         entries | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def foreach(aDirectoryName) | 
					
						
							| 
									
										
										
										
											2003-08-20 22:10:20 +08:00
										 |  |  |         unless @file.stat(aDirectoryName).directory? | 
					
						
							|  |  |  |           raise Errno::ENOTDIR, aDirectoryName | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2003-08-20 23:30:03 +08:00
										 |  |  |         path = @file.expand_path(aDirectoryName).ensure_end("/") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         subDirEntriesRegex = Regexp.new("^#{path}([^/]+)$") | 
					
						
							| 
									
										
										
										
											2003-08-21 04:44:12 +08:00
										 |  |  |         @mappedZip.each {  | 
					
						
							| 
									
										
										
										
											2003-08-20 23:30:03 +08:00
										 |  |  |           |fileName| | 
					
						
							|  |  |  |           match = subDirEntriesRegex.match(fileName) | 
					
						
							| 
									
										
										
										
											2003-08-21 04:44:12 +08:00
										 |  |  |           yield(match[1]) unless match == nil | 
					
						
							| 
									
										
										
										
											2003-08-20 23:30:03 +08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2003-08-20 22:10:20 +08:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2003-08-21 04:44:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-20 22:10:20 +08:00
										 |  |  |       def delete(entryName) | 
					
						
							|  |  |  |         unless @file.stat(entryName).directory? | 
					
						
							|  |  |  |           raise Errno::EINVAL, "Invalid argument - #{entryName}" | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2003-08-20 23:30:03 +08:00
										 |  |  |         @mappedZip.remove(entryName) | 
					
						
							| 
									
										
										
										
											2003-08-20 22:10:20 +08:00
										 |  |  |       end | 
					
						
							|  |  |  |       alias rmdir  delete | 
					
						
							|  |  |  |       alias unlink delete | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |       def mkdir(entryName, permissionInt = 0) | 
					
						
							| 
									
										
										
										
											2003-08-20 23:30:03 +08:00
										 |  |  |         @mappedZip.mkdir(entryName, permissionInt) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |        | 
					
						
							| 
									
										
										
										
											2003-08-21 00:08:07 +08:00
										 |  |  |       def chroot(*args) | 
					
						
							|  |  |  |       	raise NotImplementedError, "The chroot() function is not implemented" | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-20 23:30:03 +08:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-21 20:19:00 +08:00
										 |  |  |     class ZipFsDirIterator | 
					
						
							|  |  |  |       include Enumerable | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def initialize(arrayOfFileNames) | 
					
						
							|  |  |  |         @fileNames = arrayOfFileNames | 
					
						
							|  |  |  |         @index = 0
 | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def close | 
					
						
							|  |  |  |         @fileNames = nil | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def each(&aProc) | 
					
						
							|  |  |  |         raise IOError, "closed directory" if @fileNames == nil | 
					
						
							|  |  |  |         @fileNames.each(&aProc) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def read | 
					
						
							|  |  |  |         raise IOError, "closed directory" if @fileNames == nil | 
					
						
							|  |  |  |         @fileNames[(@index+=1)-1] | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def rewind | 
					
						
							|  |  |  |         raise IOError, "closed directory" if @fileNames == nil | 
					
						
							|  |  |  |         @index = 0
 | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def seek(anIntegerPosition) | 
					
						
							|  |  |  |         raise IOError, "closed directory" if @fileNames == nil | 
					
						
							|  |  |  |         @index = anIntegerPosition | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def tell | 
					
						
							|  |  |  |         raise IOError, "closed directory" if @fileNames == nil | 
					
						
							|  |  |  |         @index | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-20 23:30:03 +08:00
										 |  |  |     # All access to ZipFile from ZipFsFile and ZipFsDir goes through a | 
					
						
							|  |  |  |     # ZipFileNameMapper, which has one responsibility: ensure | 
					
						
							|  |  |  |     class ZipFileNameMapper | 
					
						
							|  |  |  |       include Enumerable | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def initialize(zipFile) | 
					
						
							|  |  |  |         @zipFile = zipFile | 
					
						
							|  |  |  |         @pwd = "/" | 
					
						
							| 
									
										
										
										
											2003-08-20 22:10:20 +08:00
										 |  |  |       end | 
					
						
							|  |  |  |        | 
					
						
							| 
									
										
										
										
											2003-08-20 23:30:03 +08:00
										 |  |  |       attr_accessor :pwd | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |       def find_entry(fileName) | 
					
						
							|  |  |  |         @zipFile.find_entry(expand_to_entry(fileName)) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |       def get_entry(fileName) | 
					
						
							|  |  |  |         @zipFile.get_entry(expand_to_entry(fileName)) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def get_input_stream(fileName, &aProc) | 
					
						
							|  |  |  |         @zipFile.get_input_stream(expand_to_entry(fileName), &aProc) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |       def get_output_stream(fileName, &aProc) | 
					
						
							|  |  |  |         @zipFile.get_output_stream(expand_to_entry(fileName), &aProc) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def read(fileName) | 
					
						
							|  |  |  |         @zipFile.read(expand_to_entry(fileName)) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |       def remove(fileName) | 
					
						
							|  |  |  |         @zipFile.remove(expand_to_entry(fileName)) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def rename(fileName, newName, &continueOnExistsProc) | 
					
						
							|  |  |  |         @zipFile.rename(expand_to_entry(fileName), expand_to_entry(newName),  | 
					
						
							|  |  |  |                         &continueOnExistsProc) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def mkdir(fileName, permissionInt = 0) | 
					
						
							|  |  |  |         @zipFile.mkdir(expand_to_entry(fileName), permissionInt) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       # Turns entries into strings and adds leading / | 
					
						
							|  |  |  |       # and removes trailing slash on directories | 
					
						
							|  |  |  |       def each | 
					
						
							|  |  |  |         @zipFile.each { | 
					
						
							|  |  |  |           |e| | 
					
						
							|  |  |  |           yield("/"+e.to_s.chomp("/")) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2003-08-21 00:08:07 +08:00
										 |  |  |        | 
					
						
							| 
									
										
										
										
											2003-08-20 22:10:20 +08:00
										 |  |  |       def expand_path(aPath) | 
					
						
							|  |  |  |         expanded = aPath.starts_with("/") ? aPath : @pwd.ensure_end("/") + aPath | 
					
						
							|  |  |  |         expanded.gsub!(/\/\.(\/|$)/, "") | 
					
						
							|  |  |  |         expanded.gsub!(/[^\/]+\/\.\.(\/|$)/, "") | 
					
						
							|  |  |  |         expanded.empty? ? "/" : expanded | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2003-08-20 23:30:03 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       private | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-20 22:10:20 +08:00
										 |  |  |       def expand_to_entry(aPath) | 
					
						
							|  |  |  |         expand_path(aPath).lchop | 
					
						
							| 
									
										
										
										
											2003-08-19 21:07:24 +08:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2003-08-20 21:39:56 +08:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2003-08-19 21:07:24 +08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-13 16:00:52 +08:00
										 |  |  |   class ZipFile | 
					
						
							|  |  |  |     include ZipFileSystem | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2002-07-26 22:12:34 +08:00
										 |  |  | end | 
					
						
							| 
									
										
										
										
											2003-08-13 16:00:52 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-13 16:02:32 +08:00
										 |  |  | # Copyright (C) 2002, 2003 Thomas Sondergaard | 
					
						
							|  |  |  | # rubyzip is free software; you can redistribute it and/or | 
					
						
							|  |  |  | # modify it under the terms of the ruby license. |