sys-filesystem 0.2.0-x86-mswin32-60

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES ADDED
@@ -0,0 +1,15 @@
1
+ == 0.2.0 - 30-Dec-2008
2
+ * Added the Filesystem.mounts method for iterating over mount or volume
3
+ information.
4
+
5
+ == 0.1.1 - 28-Mar-2007
6
+ * Bug fix for BSD flavors. Thanks go to Jeremy Kemper and Ole Christian
7
+ Rynning for the spot.
8
+ * Bug fix for OS X (along the same lines as the BSD fix). Thanks go to
9
+ Aurelian Dehay for the spot.
10
+ * Some Rdoc improvements for the C extension.
11
+ * Tweaks to the gemspec.
12
+ * Added synopsis to the README.
13
+
14
+ == 0.1.0 - 17-Nov-2006
15
+ * Initial release. Alpha. Code is stable, but API is not.
data/MANIFEST ADDED
@@ -0,0 +1,13 @@
1
+ * MANIFEST
2
+ * CHANGES
3
+ * Rakefile
4
+ * README
5
+ * sys-fileystem.gemspec
6
+ * examples/example_stat.rb
7
+ * doc/sys-filesystem.txt
8
+ * ext/extconf.rb
9
+ * ext/filesystem.c
10
+ * lib/sys/filesystem.rb
11
+ * test/test_sys_filesystem.rb
12
+ * test/test_sys_filesystem_unix
13
+ * test/test_sys_filesystem_windows
data/README ADDED
@@ -0,0 +1,72 @@
1
+ = Description
2
+ A Ruby interface for getting file system information.
3
+
4
+ = Prerequisites
5
+ === MS Windows
6
+ * windows-pr, 0.9.8 or later.
7
+
8
+ = Installation
9
+ rake test (optional)
10
+ rake install (non-gem) OR rake install_gem (gem)
11
+
12
+ = Synopsis
13
+ require 'sys/filesystem'
14
+ include Sys
15
+
16
+ p Filesystem.stat("/")
17
+
18
+ # Sample output
19
+
20
+ #<Sys::Filesystem::Stat:0x517440
21
+ @base_type = "ufs",
22
+ @flags = 4,
23
+ @files_available = 3817457,
24
+ @block_size = 8192,
25
+ @blocks_available = 19957633,
26
+ @blocks = 34349612,
27
+ @name_max = 255,
28
+ @path = "/",
29
+ @filesystem_id = 35651592,
30
+ @files = 4135040,
31
+ @fragment_size = 1024,
32
+ @files_free = 3817457,
33
+ @blocks_free = 20301129
34
+ >
35
+
36
+ Filesystem.mounts{ |mount| p mount }
37
+
38
+ = Notes
39
+ === MS Windows
40
+ This is a pure Ruby implementation using the windows-pr package, which in
41
+ turn wraps native Windows functions.
42
+ === UNIX
43
+ This is a C extension that wraps statvfs, etc.
44
+
45
+ = Sample code
46
+ Run 'rake example' if you want to see a basic sample run. The actual code
47
+ is 'example_stat.rb' in the 'examples' directory. Modify it as you see fit.
48
+
49
+ = Known Bugs
50
+ None that I'm aware of. Please report bugs on the project page at
51
+ http://www.rubyforge.org/projects/sysutils.
52
+
53
+ = Future Plans
54
+ Suggestions welcome.
55
+
56
+ = Acknowledgements
57
+ Mike Hall, for ideas and code that I borrowed from his 'filesystem' package.
58
+ Park Heesob, for implementation and API ideas for the MS Windows version.
59
+
60
+ = Copyright
61
+ (C) 2003-2008 Daniel J. Berger
62
+ All Rights Reserved
63
+
64
+ = Warranty
65
+ This library is provided "as is" and without any express or
66
+ implied warranties, including, without limitation, the implied
67
+ warranties of merchantability and fitness for a particular purpose.
68
+
69
+ = Author
70
+ Daniel J. Berger
71
+ djberg96 at gmail dot com
72
+ imperator on IRC (irc.freenode.net)
data/Rakefile ADDED
@@ -0,0 +1,72 @@
1
+ require 'rake'
2
+ require 'rake/clean'
3
+ require 'rake/testtask'
4
+ include Config
5
+
6
+ desc "Clean the build files for the sys-filesystem source for UNIX systems"
7
+ task :clean do
8
+ Dir.chdir('examples') do
9
+ FileUtils.rm_rf('sys') if File.exists?('sys')
10
+ end
11
+
12
+ unless CONFIG['host_os'].match('mswin')
13
+ file = 'sys/filesystem.' + CONFIG['DLEXT']
14
+ Dir.chdir('ext') do
15
+ sh 'make distclean' rescue nil
16
+ rm file if File.exists?(file)
17
+ end
18
+ end
19
+ end
20
+
21
+ desc "Build the sys-filesystem library on UNIX systems (but don't install it)"
22
+ task :build => [:clean] do
23
+ unless CONFIG['host_os'].match('mswin')
24
+ file = 'filesystem.' + CONFIG['DLEXT']
25
+ Dir.chdir('ext') do
26
+ ruby 'extconf.rb'
27
+ sh 'make'
28
+ mv file, 'sys'
29
+ end
30
+ end
31
+ end
32
+
33
+ if CONFIG['host_os'].match('mswin')
34
+ desc "Install the sys-filesystem library"
35
+ task :install do
36
+ install_dir = File.join(CONFIG['sitelibdir'], 'sys')
37
+ Dir.mkdir(install_dir) unless File.exists?(install_dir)
38
+ FileUtils.cp('lib/sys/filesystem.rb', install_dir, :verbose => true)
39
+ end
40
+ else
41
+ desc "Install the sys-filesystem library"
42
+ task :install => [:build] do
43
+ Dir.chdir('ext') do
44
+ sh 'make install'
45
+ end
46
+ end
47
+ end
48
+
49
+ desc "Run the test suite"
50
+ Rake::TestTask.new("test") do |t|
51
+ unless CONFIG['host_os'].match('mswin')
52
+ task :test => :build
53
+ t.libs << 'ext'
54
+ t.libs.delete('lib')
55
+ end
56
+ t.warning = true
57
+ t.verbose = true
58
+ t.test_files = FileList['test/test_sys_filesystem.rb']
59
+ end
60
+
61
+ desc "Run the example program"
62
+ task :example => [:build] do |t|
63
+ Dir.chdir('examples') do
64
+ Dir.mkdir('sys') unless File.exists?('sys')
65
+ end
66
+
67
+ FileUtils.cp('ext/sys/filesystem.' + Config::CONFIG['DLEXT'], 'examples/sys')
68
+
69
+ Dir.chdir('examples') do
70
+ ruby 'example_stat.rb'
71
+ end
72
+ end
@@ -0,0 +1,165 @@
1
+ = Description
2
+ A Ruby interface for getting filesystem information.
3
+
4
+ = Synopsis
5
+ require 'sys/filesystem'
6
+ include Sys
7
+
8
+ p Filesystem.stat("/") # => Sys::Filesystem::Stat object
9
+
10
+ Filesystem.mounts{ |mount|
11
+ p mount
12
+ }
13
+
14
+ = Constants
15
+ == Sys::Filesystem
16
+ VERSION
17
+ The version of this package, returned as a string.
18
+
19
+ == Sys::Filesystem::Stat
20
+ RDONLY
21
+ Read only filesystem.
22
+
23
+ See the +flags+ method for more information.
24
+
25
+ NOSUID
26
+ Filesystem does not support suid or sgid semantics.
27
+
28
+ See the +flags+ method for more information.
29
+
30
+ NOTRUNC
31
+ Filesystem does not truncate file names longer than +name_max+. Not
32
+ supported on all platforms.
33
+
34
+ See the +flags+ method for more information.
35
+
36
+ = Class Methods
37
+ === Sys::Filesystem
38
+ Sys::Filesystem.stat(path)
39
+ Returns a Filesystem::Stat object containing information about the
40
+ +path+ filesystem.
41
+
42
+ Sys::Filesystem.mounts
43
+ Returns an array of Filesystem::Mount objects containing information
44
+ about the mount points available on your system.
45
+
46
+ In block form this method yields each Mount object in turn instead
47
+ of returning an array.
48
+
49
+ = Instance Methods
50
+ === Sys::Filesystem::Mount
51
+ name
52
+ The name of the mounted resource.
53
+
54
+ On MS Windows this is the device mapping.
55
+
56
+ mount_time
57
+ The last time the volume was mounted.
58
+
59
+ On MS Windows this is your system's boot time.
60
+
61
+ mount_type
62
+ The type of mount, e.g. NFS, NTFS.
63
+
64
+ mount_point
65
+ The volume mount point.
66
+
67
+ On MS Windows this is the volume letter.
68
+
69
+ options
70
+ A list of comma separated options that denote properties of the volume.
71
+
72
+ pass_number
73
+ The number of the filesystem check, or nil if not present.
74
+
75
+ This is always nil on MS Windows.
76
+
77
+ frequency
78
+ The dump frequency in days, or nil if not present or supported.
79
+
80
+ This is always nil on MS Windows.
81
+
82
+ === Sys::Filesystem::Stat
83
+ base_type
84
+ The filesystem type, e.g. UFS.
85
+
86
+ block_size
87
+ The preferred system block size.
88
+
89
+ blocks
90
+ The total number of +fragment_size+ blocks in the filesystem.
91
+
92
+ blocks_available
93
+ The number of free blocks available to unprivileged processes.
94
+
95
+ blocks_free
96
+ The total number of free blocks in the filesystem.
97
+
98
+ files
99
+ The total number of files/inodes that can be created.
100
+
101
+ files_free
102
+ The total number of free files/inodes on the file system.
103
+
104
+ filesystem_id
105
+ The filesystem identifier.
106
+
107
+ flags
108
+ A bit mask of flags. See the 'Constants' section for a list of flags.
109
+
110
+ fragment_size
111
+ The fragment size, i.e. fundamental file system block size.
112
+
113
+ inodes
114
+ Alias for +files+.
115
+
116
+ inodes_free
117
+ Alias for +files_free+.
118
+
119
+ inodes_available
120
+ Alias for +files_available+.
121
+
122
+ name_max
123
+ The maximum length of a file name permitted on the file system.
124
+
125
+ path
126
+ The path of the filesystem.
127
+
128
+ = Fixnum helper methods
129
+ Fixnum#to_gb
130
+ Returns a number in terms of gigabytes.
131
+
132
+ Fixnum#to_kb
133
+ Returns a number in terms of kilobytes
134
+
135
+ Fixnum#to_mb
136
+ Returns a number in terms of megabytes
137
+
138
+ == Known Bugs
139
+ None that I am aware of. Please log any bugs you find on the project
140
+ website at http://www.rubyforge.org/projects/sysutils.
141
+
142
+ == License
143
+ Ruby's
144
+
145
+ == Copyright
146
+ Copyright 2002-2008, Daniel J. Berger
147
+
148
+ All Rights Reserved. This module is free software. It may be used,
149
+ redistributed and/or modified under the same terms as Ruby itself.
150
+
151
+ == Warranty
152
+ This library is provided "as is" and without any express or
153
+ implied warranties, including, without limitation, the implied
154
+ warranties of merchantability and fitness for a particular purpose.
155
+
156
+ == Acknowledgements
157
+ Mike Hall for his original source code.
158
+
159
+ == Author
160
+ Daniel J. Berger
161
+ djberg96 at nospam at gmail dot com
162
+ imperator on IRC (Freenode)
163
+
164
+ == See Also
165
+ mount
@@ -0,0 +1,24 @@
1
+ ######################################################################
2
+ # example_stat.rb
3
+ #
4
+ # Example program that demonstrates the FileSystem.stat method.
5
+ # Use the 'rake example' task to run this program.
6
+ ######################################################################
7
+ require 'sys/filesystem'
8
+ include Sys
9
+
10
+ p Filesystem::VERSION
11
+
12
+ stat = Filesystem.stat("/")
13
+ puts "Path: " + stat.path
14
+ puts "Block size: " + stat.block_size.to_s
15
+ puts "Fragment size: " + stat.fragment_size.to_s
16
+ puts "Blocks free: " + stat.blocks_free.to_s
17
+ puts "Blocks available: " + stat.blocks_available.to_s
18
+ puts "Files/Inodes: " + stat.files.to_s
19
+ puts "Files/Inodes free: " + stat.files_free.to_s
20
+ puts "Files/Inodes available: " + stat.files_available.to_s
21
+ puts "File system id: " + stat.filesystem_id.to_s
22
+ puts "Base type: " + stat.base_type if stat.base_type
23
+ puts "Flags: " + stat.flags.to_s
24
+ puts "Name max: " + stat.name_max.to_s
@@ -0,0 +1,392 @@
1
+ require 'windows/error'
2
+ require 'windows/filesystem'
3
+ require 'windows/volume'
4
+ require 'windows/handle'
5
+ require 'windows/limits'
6
+ require 'socket'
7
+ require 'win32ole'
8
+ require 'date'
9
+ require 'time'
10
+
11
+ # The Sys module serves as a namespace only.
12
+ module Sys
13
+
14
+ # The Filesystem class encapsulates information about your filesystem.
15
+ class Filesystem
16
+ include Windows::Error
17
+ include Windows::Handle
18
+ include Windows::Limits
19
+
20
+ extend Windows::Error
21
+ extend Windows::FileSystem
22
+ extend Windows::Volume
23
+
24
+ # Error typically raised if any of the Sys::Filesystem methods fail.
25
+ class Error < StandardError; end
26
+
27
+ CASE_SENSITIVE_SEARCH = 0x00000001
28
+ CASE_PRESERVED_NAMES = 0x00000002
29
+ UNICODE_ON_DISK = 0x00000004
30
+ PERSISTENT_ACLS = 0x00000008
31
+ FILE_COMPRESSION = 0x00000010
32
+ VOLUME_QUOTAS = 0x00000020
33
+ SUPPORTS_SPARSE_FILES = 0x00000040
34
+ SUPPORTS_REPARSE_POINTS = 0x00000080
35
+ SUPPORTS_REMOTE_STORAGE = 0x00000100
36
+ VOLUME_IS_COMPRESSED = 0x00008000
37
+ SUPPORTS_OBJECT_IDS = 0x00010000
38
+ SUPPORTS_ENCRYPTION = 0x00020000
39
+ NAMED_STREAMS = 0x00040000
40
+ READ_ONLY_VOLUME = 0x00080000
41
+
42
+ VERSION = '0.2.0'
43
+
44
+ class Mount
45
+ # The name of the volume. This is the device mapping.
46
+ attr_reader :name
47
+
48
+ # The last time the volume was mounted. For MS Windows this equates
49
+ # to your system's boot time.
50
+ attr_reader :mount_time
51
+
52
+ # The type of mount, e.g. NTFS, UDF, etc.
53
+ attr_reader :mount_type
54
+
55
+ # The volume mount point, e.g. 'C:\'
56
+ attr_reader :mount_point
57
+
58
+ # Various comma separated options that reflect the volume's features
59
+ attr_reader :options
60
+
61
+ # Always nil on MS Windows. Provided for interface compatibility only.
62
+ attr_reader :pass_number
63
+
64
+ # Always nil on MS Windows. Provided for interface compatibility only.
65
+ attr_reader :frequency
66
+
67
+ alias fsname name
68
+ alias dir mount_point
69
+ alias opts options
70
+ alias passno pass_number
71
+ alias freq frequency
72
+ end
73
+
74
+ class Stat
75
+ # The path of the file system.
76
+ attr_reader :path
77
+
78
+ # The file system block size. MS Windows typically defaults to 4096.
79
+ attr_reader :block_size
80
+
81
+ # Fragment size. Meaningless at the moment.
82
+ attr_reader :fragment_size
83
+
84
+ # The total number of blocks available (used or unused) on the file
85
+ # system.
86
+ attr_reader :blocks
87
+
88
+ # The total number of unused blocks.
89
+ attr_reader :blocks_free
90
+
91
+ # The total number of unused blocks available to unprivileged
92
+ # processes. Identical to +blocks+ at the moment.
93
+ attr_reader :blocks_available
94
+
95
+ # Total number of files/inodes that can be created on the file system.
96
+ # This attribute is always nil on MS Windows.
97
+ attr_reader :files
98
+
99
+ # Total number of free files/inodes that can be created on the file
100
+ # system. This attribute is always nil on MS Windows.
101
+ attr_reader :files_free
102
+
103
+ # Total number of available files/inodes for unprivileged processes
104
+ # that can be created on the file system. This attribute is always
105
+ # nil on MS Windows.
106
+ attr_reader :files_available
107
+
108
+ # The file system volume id.
109
+ attr_reader :filesystem_id
110
+
111
+ # A bit mask of file system flags.
112
+ attr_reader :flags
113
+
114
+ # The maximum length of a file name permitted on the file system.
115
+ attr_reader :name_max
116
+
117
+ # The file system type, e.g. NTFS, FAT, etc.
118
+ attr_reader :base_type
119
+
120
+ alias inodes files
121
+ alias inodes_free files_free
122
+ alias inodes_available files_available
123
+ end
124
+
125
+ # Yields a Filesystem::Mount object for each volume on your system in
126
+ # block form. Returns an array of Filesystem::Mount objects in non-block
127
+ # form.
128
+ #
129
+ # Example:
130
+ #
131
+ # Filesystem.mounts{ |mount|
132
+ # p mt.name # => \\Device\\HarddiskVolume1
133
+ # p mt.mount_point # => C:\
134
+ # p mt.mount_time # => Thu Dec 18 20:12:08 -0700 2008
135
+ # p mt.mount_type # => NTFS
136
+ # p mt.options # => casepres,casesens,ro,unicode
137
+ # p mt.pass_number # => nil
138
+ # p mt.dump_freq # => nil
139
+ # }
140
+ #
141
+ # This method is a bit of a fudge for MS Windows in the name of interface
142
+ # compatibility because this method deals with volumes, not actual mount
143
+ # points. But, I believe it provides the sort of information many users
144
+ # want at a glance.
145
+ #
146
+ # The possible values for the +options+ and their meanings are as follows:
147
+ #
148
+ # casepres => The filesystem preserves the case of file names when it places a name on disk.
149
+ # casesens => The filesystem supports case-sensitive file names.
150
+ # compression => The filesystem supports file-based compression.
151
+ # namedstreams => The filesystem supports named streams.
152
+ # pacls => The filesystem preserves and enforces access control lists.
153
+ # ro => The filesystem is read-only.
154
+ # encryption => The filesystem supports the Encrypted File System (EFS).
155
+ # objids => The filesystem supports object identifiers.
156
+ # rpoints => The filesystem supports reparse points.
157
+ # sparse => The filesystem supports sparse files.
158
+ # unicode => The filesystem supports Unicode in file names as they appear on disk.
159
+ # compressed => The filesystem is compressed.
160
+ #
161
+ def self.mounts
162
+ buffer = 0.chr * MAXPATH
163
+ length = GetLogicalDriveStrings(buffer.size, buffer)
164
+
165
+ if length == 0
166
+ raise Error, get_last_error
167
+ end
168
+
169
+ mounts = block_given? ? nil : []
170
+
171
+ # Try again if it fails
172
+ if length > buffer.size
173
+ buffer = 0.chr * length
174
+ if GetLogicalDriveStrings(buffer.size, buffer) == 0
175
+ raise Error, get_last_error
176
+ end
177
+ end
178
+
179
+ boot_time = get_boot_time
180
+
181
+ drives = buffer.strip.split("\0")
182
+
183
+ drives.each{ |drive|
184
+ mount = Mount.new
185
+ volume = 0.chr * MAXPATH
186
+ fsname = 0.chr * MAXPATH
187
+
188
+ mount.instance_variable_set(:@mount_point, drive)
189
+ mount.instance_variable_set(:@mount_time, boot_time)
190
+
191
+ volume_serial_number = [0].pack('L')
192
+ max_component_length = [0].pack('L')
193
+ filesystem_flags = [0].pack('L')
194
+
195
+ bool = GetVolumeInformation(
196
+ drive,
197
+ volume,
198
+ volume.size,
199
+ volume_serial_number,
200
+ max_component_length,
201
+ filesystem_flags,
202
+ fsname,
203
+ fsname.size
204
+ )
205
+
206
+ # Skip unmounted floppies or cd-roms
207
+ unless bool
208
+ errnum = GetLastError()
209
+ if errnum == ERROR_NOT_READY
210
+ next
211
+ else
212
+ raise Error, get_last_error(errnum)
213
+ end
214
+ end
215
+
216
+ filesystem_flags = filesystem_flags.unpack('L')[0]
217
+
218
+ name = 0.chr * MAXPATH
219
+
220
+ if QueryDosDevice(drive[0,2], name, name.size) == 0
221
+ raise Error, get_last_error
222
+ end
223
+
224
+ mount.instance_variable_set(:@name, name.strip)
225
+ mount.instance_variable_set(:@mount_type, fsname.strip)
226
+ mount.instance_variable_set(:@options, get_options(filesystem_flags))
227
+
228
+ if block_given?
229
+ yield mount
230
+ else
231
+ mounts << mount
232
+ end
233
+ }
234
+
235
+ mounts # Nil if the block form was used.
236
+ end
237
+
238
+ # Returns a Filesystem::Stat object that contains information about the
239
+ # +path+ file system.
240
+ #
241
+ # Example:
242
+ #
243
+ # File.stat("C:\\")
244
+ # File.stat("C:\\Documents and Settings\\some_user")
245
+ #
246
+ def self.stat(path)
247
+ bytes_avail = [0].pack('Q')
248
+ bytes_free = [0].pack('Q')
249
+ total_bytes = [0].pack('Q')
250
+
251
+ unless GetDiskFreeSpaceEx(path, bytes_avail, total_bytes, bytes_free)
252
+ raise Error, get_last_error
253
+ end
254
+
255
+ bytes_avail = bytes_avail.unpack('Q').first
256
+ bytes_free = bytes_free.unpack('Q').first
257
+ total_bytes = total_bytes.unpack('Q').first
258
+
259
+ sectors = [0].pack('Q')
260
+ bytes = [0].pack('Q')
261
+ free = [0].pack('Q')
262
+ total = [0].pack('Q')
263
+
264
+ unless GetDiskFreeSpace(path, sectors, bytes, free, total)
265
+ raise Error, get_last_error
266
+ end
267
+
268
+ sectors = sectors.unpack('Q').first
269
+ bytes = bytes.unpack('Q').first
270
+ free = free.unpack('Q').first
271
+ total = total.unpack('Q').first
272
+
273
+ block_size = sectors * bytes
274
+ blocks_avail = total_bytes / block_size
275
+ blocks_free = bytes_free / block_size
276
+
277
+ vol_name = 0.chr * 260
278
+ base_type = 0.chr * 260
279
+ vol_serial = [0].pack('L')
280
+ name_max = [0].pack('L')
281
+ flags = [0].pack('L')
282
+
283
+ bool = GetVolumeInformation(
284
+ path,
285
+ vol_name,
286
+ vol_name.size,
287
+ vol_serial,
288
+ name_max,
289
+ flags,
290
+ base_type,
291
+ base_type.size
292
+ )
293
+
294
+ unless bool
295
+ raise Error, get_last_error
296
+ end
297
+
298
+ vol_serial = vol_serial.unpack('L').first
299
+ name_max = name_max.unpack('L').first
300
+ flags = flags.unpack('L').first
301
+ base_type = base_type[/^[^\0]*/]
302
+
303
+ stat_obj = Stat.new
304
+ stat_obj.instance_variable_set(:@path, path)
305
+ stat_obj.instance_variable_set(:@block_size, block_size)
306
+ stat_obj.instance_variable_set(:@blocks, blocks_avail)
307
+ stat_obj.instance_variable_set(:@blocks_available, blocks_avail)
308
+ stat_obj.instance_variable_set(:@blocks_free, blocks_free)
309
+ stat_obj.instance_variable_set(:@name_max, name_max)
310
+ stat_obj.instance_variable_set(:@base_type, base_type)
311
+ stat_obj.instance_variable_set(:@flags, flags)
312
+ stat_obj.instance_variable_set(:@filesystem_id, vol_serial)
313
+
314
+ stat_obj.freeze # Read-only object
315
+ end
316
+
317
+ private
318
+
319
+ # Used to get the boot time of the system, which is used for mount_time
320
+ # attribute within the File.mounts method.
321
+ #
322
+ def self.get_boot_time
323
+ host = Socket.gethostname
324
+ cs = "winmgmts://#{host}/root/cimv2"
325
+ begin
326
+ wmi = WIN32OLE.connect(cs)
327
+ rescue WIN32OLERuntimeError => e
328
+ raise Error, e
329
+ else
330
+ query = 'select LastBootupTime from Win32_OperatingSystem'
331
+ results = wmi.ExecQuery(query)
332
+ results.each{ |ole|
333
+ time_array = Time.parse(ole.LastBootupTime.split('.').first)
334
+ return Time.mktime(*time_array)
335
+ }
336
+ end
337
+ end
338
+
339
+ # Private method that converts filesystem flags into a comma separated
340
+ # list of strings. The presentation is meant as a rough analogue to the
341
+ # way options are presented for Unix filesystems.
342
+ #
343
+ def self.get_options(flags)
344
+ str = ""
345
+ str << " casepres" if CASE_PRESERVED_NAMES & flags > 0
346
+ str << " casesens" if CASE_SENSITIVE_SEARCH & flags > 0
347
+ str << " compression" if FILE_COMPRESSION & flags > 0
348
+ str << " namedstreams" if NAMED_STREAMS & flags > 0
349
+ str << " pacls" if PERSISTENT_ACLS & flags > 0
350
+ str << " ro" if READ_ONLY_VOLUME & flags > 0
351
+ str << " encryption" if SUPPORTS_ENCRYPTION & flags > 0
352
+ str << " objids" if SUPPORTS_OBJECT_IDS & flags > 0
353
+ str << " rpoints" if SUPPORTS_REPARSE_POINTS & flags > 0
354
+ str << " sparse" if SUPPORTS_SPARSE_FILES & flags > 0
355
+ str << " unicode" if UNICODE_ON_DISK & flags > 0
356
+ str << " compressed" if VOLUME_IS_COMPRESSED & flags > 0
357
+
358
+ str.tr!(' ', ',')
359
+ str = str[1..-1] # Ignore the first comma
360
+ str
361
+ end
362
+
363
+ end
364
+ end
365
+
366
+ # Some convenient methods for converting bytes to kb, mb, and gb.
367
+ #
368
+ class Fixnum
369
+ # call-seq:
370
+ # <tt>fix</tt>.to_kb
371
+ #
372
+ # Returns +fix+ in terms of kilobytes.
373
+ def to_kb
374
+ self / 1024
375
+ end
376
+
377
+ # call-seq:
378
+ # <tt>fix</tt>.to_mb
379
+ #
380
+ # Returns +fix+ in terms of megabytes.
381
+ def to_mb
382
+ self / 1048576
383
+ end
384
+
385
+ # call-seq:
386
+ # <tt>fix</tt>.to_gb
387
+ #
388
+ # Returns +fix+ in terms of gigabytes.
389
+ def to_gb
390
+ self / 1073741824
391
+ end
392
+ end
@@ -0,0 +1,36 @@
1
+ require 'rubygems'
2
+
3
+ spec = Gem::Specification.new do |gem|
4
+ gem.name = 'sys-filesystem'
5
+ gem.version = '0.2.0'
6
+ gem.author = 'Daniel J. Berger'
7
+ gem.email = 'djberg96@gmail.com'
8
+ gem.homepage = 'http://www.rubyforge.org/projects/sysutils'
9
+ gem.platform = Gem::Platform::RUBY
10
+ gem.summary = 'A Ruby interface for getting file system information.'
11
+ gem.description = 'A Ruby interface for getting file system information.'
12
+ gem.test_file = 'test/test_sys_filesystem.rb'
13
+ gem.has_rdoc = true
14
+ gem.extra_rdoc_files = ['CHANGES', 'README', 'MANIFEST']
15
+ gem.rubyforge_project = 'sysutils'
16
+ files = Dir["doc/*"] + Dir["examples/*"] + Dir["test/*"] + Dir["[A-Z]*"]
17
+ files.delete_if{ |item| item.include?('CVS') }
18
+ gem.files = files
19
+ end
20
+
21
+ if $PROGRAM_NAME == __FILE__
22
+ if RUBY_PLATFORM.match('mswin')
23
+ spec.required_ruby_version = '>= 1.8.2'
24
+ spec.files += ['lib/sys/filesystem.rb']
25
+ spec.platform = Gem::Platform::CURRENT
26
+ spec.add_dependency('windows-pr', '>= 0.6.0')
27
+ else
28
+ spec.required_ruby_version = '>= 1.8.0'
29
+ spec.extensions = ['ext/extconf.rb']
30
+ spec.files += Dir["ext/**/*"]
31
+ spec.extra_rdoc_files << 'ext/sys/filesystem.c'
32
+ end
33
+
34
+ Gem.manage_gems if Gem::RubyGemsVersion.to_f < 1.0
35
+ Gem::Builder.new(spec).build
36
+ end
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift File.dirname(File.expand_path(__FILE__))
2
+
3
+ require 'rbconfig'
4
+
5
+ if Config::CONFIG['host_os'].match('mswin')
6
+ require 'test_sys_filesystem_windows'
7
+ else
8
+ require 'test_sys_filesystem_unix'
9
+ end
@@ -0,0 +1,234 @@
1
+ ####################################################################
2
+ # tc_unix.rb
3
+ #
4
+ # Test case for the Sys::Filesystem.stat method and related stuff.
5
+ # This test suite should be run via the 'rake test' task.
6
+ ####################################################################
7
+ require 'rubygems'
8
+ gem 'test-unit'
9
+
10
+ require 'test/unit'
11
+ require 'sys/filesystem'
12
+ include Sys
13
+
14
+ class TC_Sys_Filesystem_Unix < Test::Unit::TestCase
15
+ def self.startup
16
+ @@solaris = Config::CONFIG['host_os'] =~ /solaris/i
17
+ @@linux = Config::CONFIG['host_os'] =~ /linux/i
18
+ end
19
+
20
+ def setup
21
+ @dir = "/"
22
+ @stat = Filesystem.stat(@dir)
23
+ @mnt = Filesystem.mounts[0]
24
+ @size = 58720256
25
+ @array = []
26
+ end
27
+
28
+ def test_version
29
+ assert_equal('0.2.0', Filesystem::VERSION)
30
+ end
31
+
32
+ def test_stat_path
33
+ assert_respond_to(@stat, :path)
34
+ assert_equal("/", @stat.path)
35
+ end
36
+
37
+ def test_stat_block_size
38
+ assert_respond_to(@stat, :block_size)
39
+ assert_kind_of(Fixnum, @stat.block_size)
40
+ end
41
+
42
+ def test_stat_fragment_size
43
+ assert_respond_to(@stat, :fragment_size)
44
+ assert_kind_of(Fixnum, @stat.fragment_size)
45
+ end
46
+
47
+ def test_stat_blocks
48
+ assert_respond_to(@stat, :blocks)
49
+ assert_kind_of(Fixnum, @stat.blocks)
50
+ end
51
+
52
+ def test_stat_blocks_free
53
+ assert_respond_to(@stat, :blocks_free)
54
+ assert_kind_of(Fixnum, @stat.blocks_free)
55
+ end
56
+
57
+ def test_stat_blocks_available
58
+ assert_respond_to(@stat, :blocks_available)
59
+ assert_kind_of(Fixnum, @stat.blocks_available)
60
+ end
61
+
62
+ def test_stat_files
63
+ assert_respond_to(@stat, :files)
64
+ assert_kind_of(Fixnum, @stat.files)
65
+ end
66
+
67
+ def test_inodes_alias
68
+ assert_respond_to(@stat, :inodes)
69
+ assert_true(@stat.method(:inodes) == @stat.method(:files))
70
+ end
71
+
72
+ def test_stat_files_free
73
+ assert_respond_to(@stat, :files_free)
74
+ assert_kind_of(Fixnum, @stat.files_free)
75
+ end
76
+
77
+ def test_stat_inodes_free_alias
78
+ assert_respond_to(@stat, :inodes_free)
79
+ assert_true(@stat.method(:inodes_free) == @stat.method(:files_free))
80
+ end
81
+
82
+ def test_stat_files_available
83
+ assert_respond_to(@stat, :files_available)
84
+ assert_kind_of(Fixnum, @stat.files_available)
85
+ end
86
+
87
+ def test_stat_inodes_available_alias
88
+ assert_respond_to(@stat, :inodes_available)
89
+ assert_true(@stat.method(:inodes_available) == @stat.method(:files_available))
90
+ end
91
+
92
+ def test_stat_filesystem_id
93
+ assert_respond_to(@stat, :filesystem_id)
94
+ assert_kind_of(Integer, @stat.filesystem_id)
95
+ end
96
+
97
+ def test_stat_flags
98
+ assert_respond_to(@stat, :flags)
99
+ assert_kind_of(Fixnum, @stat.flags)
100
+ end
101
+
102
+ def test_stat_name_max
103
+ assert_respond_to(@stat, :name_max)
104
+ assert_kind_of(Fixnum, @stat.name_max)
105
+ end
106
+
107
+ def test_stat_base_type
108
+ omit_unless(@@solaris, "NOTRUNC test skipped except on Solaris")
109
+ assert_respond_to(@stat, :base_type)
110
+ assert_kind_of(String, @stat.base_type)
111
+ end
112
+
113
+ def test_stat_constants
114
+ assert_not_nil(Filesystem::Stat::RDONLY)
115
+ assert_not_nil(Filesystem::Stat::NOSUID)
116
+ omit_unless(@@solaris, "NOTRUNC test skipped except on Solaris")
117
+ assert_not_nil(Filesystem::Stat::NOTRUNC)
118
+ end
119
+
120
+ def test_stat_expected_errors
121
+ assert_raises(ArgumentError){ Filesystem.stat }
122
+ end
123
+
124
+ def test_fixnum_methods_basic
125
+ assert_respond_to(@size, :to_kb)
126
+ assert_respond_to(@size, :to_mb)
127
+ assert_respond_to(@size, :to_gb)
128
+ end
129
+
130
+ def test_to_kb
131
+ assert_equal(57344, @size.to_kb)
132
+ end
133
+
134
+ def test_to_mb
135
+ assert_equal(56, @size.to_mb)
136
+ end
137
+
138
+ def test_to_gb
139
+ assert_equal(0, @size.to_gb)
140
+ end
141
+
142
+ # Filesystem::Mount tests
143
+
144
+ def test_mounts_with_no_block
145
+ assert_nothing_raised{ @array = Filesystem.mounts }
146
+ assert_kind_of(Filesystem::Mount, @array[0])
147
+ end
148
+
149
+ def test_mounts_with_block
150
+ assert_nothing_raised{ Filesystem.mounts{ |m| @array << m } }
151
+ assert_kind_of(Filesystem::Mount, @array[0])
152
+ end
153
+
154
+ def test_mounts_high_iteration
155
+ assert_nothing_raised{ 1000.times{ @array = Filesystem.mounts } }
156
+ end
157
+
158
+ def test_mount_name
159
+ assert_respond_to(@mnt, :name)
160
+ assert_kind_of(String, @mnt.name)
161
+ end
162
+
163
+ def test_fsname_alias
164
+ assert_respond_to(@mnt, :fsname)
165
+ assert_true(@mnt.method(:fsname) == @mnt.method(:name))
166
+ end
167
+
168
+ def test_mount_point
169
+ assert_respond_to(@mnt, :mount_point)
170
+ assert_kind_of(String, @mnt.mount_point)
171
+ end
172
+
173
+ def test_dir_alias
174
+ assert_respond_to(@mnt, :dir)
175
+ assert_true(@mnt.method(:dir) == @mnt.method(:mount_point))
176
+ end
177
+
178
+ def test_mount_type
179
+ assert_respond_to(@mnt, :mount_type)
180
+ assert_kind_of(String, @mnt.mount_type)
181
+ end
182
+
183
+ def test_mount_options
184
+ assert_respond_to(@mnt, :options)
185
+ assert_kind_of(String, @mnt.options)
186
+ end
187
+
188
+ def test_opts_alias
189
+ assert_respond_to(@mnt, :opts)
190
+ assert_true(@mnt.method(:opts) == @mnt.method(:options))
191
+ end
192
+
193
+ def test_mount_time
194
+ assert_respond_to(@mnt, :mount_time)
195
+ if @@solaris
196
+ assert_kind_of(String, @mnt.mount_time)
197
+ else
198
+ assert_nil(@mnt.mount_time)
199
+ end
200
+ end
201
+
202
+ def test_mount_dump_frequency
203
+ omit_if(@@solaris, 'dump_frequency test skipped on Solaris')
204
+ assert_respond_to(@mnt, :dump_frequency)
205
+ assert_kind_of(Fixnum, @mnt.dump_frequency)
206
+ end
207
+
208
+ def test_freq_alias
209
+ assert_respond_to(@mnt, :freq)
210
+ assert_true(@mnt.method(:freq) == @mnt.method(:dump_frequency))
211
+ end
212
+
213
+ def test_mount_pass_number
214
+ omit_if(@@solaris, 'pass_number test skipped on Solaris')
215
+ assert_respond_to(@mnt, :pass_number)
216
+ assert_kind_of(Fixnum, @mnt.pass_number)
217
+ end
218
+
219
+ def test_passno_alias
220
+ assert_respond_to(@mnt, :passno)
221
+ assert_true(@mnt.method(:passno) == @mnt.method(:pass_number))
222
+ end
223
+
224
+ def teardown
225
+ @dir = nil
226
+ @stat = nil
227
+ @array = nil
228
+ end
229
+
230
+ def self.shutdown
231
+ @@solaris = nil
232
+ @@linux = nil
233
+ end
234
+ end
@@ -0,0 +1,192 @@
1
+ ####################################################################
2
+ # tc_windows.rb
3
+ #
4
+ # Test case for the Sys::Filesystem.stat method and related stuff.
5
+ # This should be run via the 'rake test' task.
6
+ ####################################################################
7
+ require 'rubygems'
8
+ gem 'test-unit'
9
+
10
+ require 'test/unit'
11
+ require 'sys/filesystem'
12
+ require 'rbconfig'
13
+ include Sys
14
+
15
+ class TC_Sys_Filesystem_Windows < Test::Unit::TestCase
16
+ def setup
17
+ @dir = '/'
18
+ @stat = Filesystem.stat(@dir)
19
+ @mount = Filesystem.mounts[0]
20
+ @size = 58720256
21
+ @array = []
22
+ end
23
+
24
+ def test_version
25
+ assert_equal('0.2.0', Filesystem::VERSION)
26
+ end
27
+
28
+ def test_stat_path
29
+ assert_respond_to(@stat, :path)
30
+ assert_equal("/", @stat.path)
31
+ end
32
+
33
+ def test_stat_block_size
34
+ assert_respond_to(@stat, :block_size)
35
+ assert_kind_of(Fixnum, @stat.block_size)
36
+ end
37
+
38
+ def test_stat_fragment_size
39
+ assert_respond_to(@stat, :fragment_size)
40
+ assert_nil(@stat.fragment_size)
41
+ end
42
+
43
+ def test_stat_blocks
44
+ assert_respond_to(@stat, :blocks)
45
+ assert_kind_of(Fixnum, @stat.blocks)
46
+ end
47
+
48
+ def test_stat_blocks_free
49
+ assert_respond_to(@stat, :blocks_free)
50
+ assert_kind_of(Fixnum, @stat.blocks_free)
51
+ end
52
+
53
+ def test_stat_blocks_available
54
+ assert_respond_to(@stat, :blocks_available)
55
+ assert_kind_of(Fixnum, @stat.blocks_available)
56
+ end
57
+
58
+ def test_stat_files
59
+ assert_respond_to(@stat, :files)
60
+ assert_respond_to(@stat, :inodes) # Alias
61
+ assert_nil(@stat.files)
62
+ end
63
+
64
+ def test_stat_files_free
65
+ assert_respond_to(@stat, :files_free)
66
+ assert_respond_to(@stat, :inodes_free) # Alias
67
+ assert_nil(@stat.files_free)
68
+ end
69
+
70
+ def test_stat_files_available
71
+ assert_respond_to(@stat, :files_available)
72
+ assert_respond_to(@stat, :inodes_available) # Alias
73
+ assert_nil(@stat.files_available)
74
+ end
75
+
76
+ def test_stat_filesystem_id
77
+ assert_respond_to(@stat, :filesystem_id)
78
+ assert_kind_of(Integer, @stat.filesystem_id)
79
+ end
80
+
81
+ def test_stat_flags
82
+ assert_respond_to(@stat, :flags)
83
+ assert_kind_of(Fixnum, @stat.flags)
84
+ end
85
+
86
+ def test_stat_name_max
87
+ assert_respond_to(@stat, :name_max)
88
+ assert_kind_of(Fixnum, @stat.name_max)
89
+ end
90
+
91
+ def test_stat_base_type
92
+ assert_respond_to(@stat, :base_type)
93
+ assert_kind_of(String, @stat.base_type)
94
+ end
95
+
96
+ def test_constants
97
+ assert_not_nil(Filesystem::CASE_SENSITIVE_SEARCH)
98
+ assert_not_nil(Filesystem::CASE_PRESERVED_NAMES)
99
+ assert_not_nil(Filesystem::UNICODE_ON_DISK)
100
+ assert_not_nil(Filesystem::PERSISTENT_ACLS)
101
+ assert_not_nil(Filesystem::FILE_COMPRESSION)
102
+ assert_not_nil(Filesystem::VOLUME_QUOTAS)
103
+ assert_not_nil(Filesystem::SUPPORTS_SPARSE_FILES)
104
+ assert_not_nil(Filesystem::SUPPORTS_REPARSE_POINTS)
105
+ assert_not_nil(Filesystem::SUPPORTS_REMOTE_STORAGE)
106
+ assert_not_nil(Filesystem::VOLUME_IS_COMPRESSED)
107
+ assert_not_nil(Filesystem::SUPPORTS_OBJECT_IDS)
108
+ assert_not_nil(Filesystem::SUPPORTS_ENCRYPTION)
109
+ assert_not_nil(Filesystem::NAMED_STREAMS)
110
+ assert_not_nil(Filesystem::READ_ONLY_VOLUME)
111
+ end
112
+
113
+ def test_stat_expected_errors
114
+ assert_raises(ArgumentError){ Filesystem.stat }
115
+ end
116
+
117
+ # Filesystem.mounts
118
+
119
+ def test_mounts_constructor_basic
120
+ assert_respond_to(Filesystem, :mounts)
121
+ assert_nothing_raised{ Filesystem.mounts }
122
+ assert_nothing_raised{ Filesystem.mounts{} }
123
+ end
124
+
125
+ def test_mounts
126
+ assert_kind_of(Array, Filesystem.mounts)
127
+ assert_kind_of(Filesystem::Mount, Filesystem.mounts[0])
128
+ end
129
+
130
+ def test_mounts_block_form
131
+ assert_nil(Filesystem.mounts{})
132
+ assert_nothing_raised{ Filesystem.mounts{ |mt| @array << mt }}
133
+ assert_kind_of(Filesystem::Mount, @array[0])
134
+ end
135
+
136
+ def test_mount_name
137
+ assert_respond_to(@mount, :name)
138
+ assert_kind_of(String, @mount.name)
139
+ end
140
+
141
+ def test_mount_time
142
+ assert_respond_to(@mount, :mount_time)
143
+ assert_kind_of(Time, @mount.mount_time)
144
+ end
145
+
146
+ def test_mount_type
147
+ assert_respond_to(@mount, :mount_type)
148
+ assert_kind_of(String, @mount.mount_type)
149
+ end
150
+
151
+ def test_mount_point
152
+ assert_respond_to(@mount, :mount_point)
153
+ assert_kind_of(String, @mount.mount_point)
154
+ end
155
+
156
+ def test_mount_options
157
+ assert_respond_to(@mount, :options)
158
+ assert_kind_of(String, @mount.options)
159
+ end
160
+
161
+ def test_pass_number
162
+ assert_respond_to(@mount, :pass_number)
163
+ assert_nil(@mount.pass_number)
164
+ end
165
+
166
+ def test_frequency
167
+ assert_respond_to(@mount, :frequency)
168
+ assert_nil(@mount.frequency)
169
+ end
170
+
171
+ def test_mounts_expected_errors
172
+ assert_raise(ArgumentError){ Filesystem.mounts("C:\\") }
173
+ end
174
+
175
+ def test_fixnum_methods
176
+ assert_respond_to(@size, :to_kb)
177
+ assert_respond_to(@size, :to_mb)
178
+ assert_respond_to(@size, :to_gb)
179
+
180
+ assert_equal(57344, @size.to_kb)
181
+ assert_equal(56, @size.to_mb)
182
+ assert_equal(0, @size.to_gb)
183
+ end
184
+
185
+ def teardown
186
+ @array = nil
187
+ @dir = nil
188
+ @stat = nil
189
+ @size = nil
190
+ @mount = nil
191
+ end
192
+ end
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sys-filesystem
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: x86-mswin32-60
6
+ authors:
7
+ - Daniel J. Berger
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-12-30 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: windows-pr
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.6.0
24
+ version:
25
+ description: A Ruby interface for getting file system information.
26
+ email: djberg96@gmail.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - CHANGES
33
+ - README
34
+ - MANIFEST
35
+ files:
36
+ - doc/sys-filesystem.txt
37
+ - examples/example_stat.rb
38
+ - test/test_sys_filesystem.rb
39
+ - test/test_sys_filesystem_unix.rb
40
+ - test/test_sys_filesystem_windows.rb
41
+ - CHANGES
42
+ - doc
43
+ - examples
44
+ - ext
45
+ - lib
46
+ - MANIFEST
47
+ - Rakefile
48
+ - README
49
+ - sys-filesystem.gemspec
50
+ - test
51
+ - lib/sys/filesystem.rb
52
+ has_rdoc: true
53
+ homepage: http://www.rubyforge.org/projects/sysutils
54
+ post_install_message:
55
+ rdoc_options: []
56
+
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: 1.8.2
64
+ version:
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: "0"
70
+ version:
71
+ requirements: []
72
+
73
+ rubyforge_project: sysutils
74
+ rubygems_version: 1.3.1
75
+ signing_key:
76
+ specification_version: 2
77
+ summary: A Ruby interface for getting file system information.
78
+ test_files:
79
+ - test/test_sys_filesystem.rb