net-smb 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +5 -0
- data/Makefile +12 -7
- data/README.md +2 -2
- data/Rakefile +42 -20
- data/ext/net_smb/depend +1 -0
- data/ext/net_smb/rb_smb.h +16 -0
- data/ext/net_smb/smb.c +14 -0
- data/ext/net_smb/smbdir.c +22 -2
- data/ext/net_smb/smbdirentry.c +5 -5
- data/ext/net_smb/smbfile.c +48 -8
- data/ext/net_smb/smbstat.c +200 -0
- data/lib/net/smb/version.rb +1 -1
- data/net-smb.gemspec +1 -0
- data/test/etc/smb.conf +1 -0
- data/test/test_net_smb.rb +241 -132
- metadata +6 -3
data/CHANGES
ADDED
data/Makefile
CHANGED
@@ -1,18 +1,23 @@
|
|
1
|
-
default: build
|
1
|
+
default: PHONY build
|
2
2
|
|
3
|
-
build:
|
3
|
+
build: PHONY
|
4
|
+
rake compile
|
4
5
|
|
5
|
-
|
6
|
-
|
6
|
+
test t: PHONY
|
7
|
+
rake test
|
8
|
+
|
9
|
+
gem: PHONY
|
7
10
|
rake build
|
8
11
|
|
9
|
-
upload:
|
12
|
+
upload: PHONY
|
13
|
+
rm -f pkg/*.gem
|
10
14
|
$(MAKE) gem
|
11
15
|
gem push pkg/*.gem
|
12
16
|
|
13
|
-
clean:
|
17
|
+
clean: PHONY
|
14
18
|
rake clean
|
15
19
|
|
16
|
-
distclean:
|
20
|
+
distclean: PHONY
|
17
21
|
rake clobber
|
18
22
|
|
23
|
+
PHONY:
|
data/README.md
CHANGED
@@ -11,7 +11,7 @@ Requirement
|
|
11
11
|
----------------------------------------------------------------------
|
12
12
|
|
13
13
|
* Ruby 1.9.3+
|
14
|
-
* Samba 3.
|
14
|
+
* Samba 3.6+ (libsmbclient)
|
15
15
|
* C compiler
|
16
16
|
|
17
17
|
Development Resources
|
@@ -23,7 +23,7 @@ Development Resources
|
|
23
23
|
Copyright
|
24
24
|
----------------------------------------------------------------------
|
25
25
|
|
26
|
-
Copyright (C)
|
26
|
+
Copyright (C) 2013 SATOH Fumiyas @ OSS Technology Corp., Japan
|
27
27
|
|
28
28
|
Licensed under the GNU General Public License version 3
|
29
29
|
|
data/Rakefile
CHANGED
@@ -1,38 +1,60 @@
|
|
1
|
+
require 'find'
|
2
|
+
|
1
3
|
begin
|
2
4
|
load 'Rakefile.local'
|
3
|
-
rescue LoadError
|
5
|
+
rescue LoadError
|
6
|
+
## Ignore
|
4
7
|
end
|
5
8
|
|
6
|
-
begin
|
7
|
-
require 'bundler/
|
8
|
-
|
9
|
+
GEM_SPEC = begin
|
10
|
+
require 'bundler/gem_helper'
|
11
|
+
helper = Bundler::GemHelper.new(Dir.pwd)
|
12
|
+
helper.install
|
13
|
+
helper.gemspec
|
14
|
+
rescue LoadError
|
15
|
+
fname = File.basename(Dir.pwd).sub(%r#^(?:ruby-)?(.+?)(?:-\d.*)?$#, '\1.gemspec')
|
16
|
+
contents = File.read(fname)
|
17
|
+
eval(contents, TOPLEVEL_BINDING, fname)
|
9
18
|
end
|
10
19
|
|
20
|
+
EXT_NAME = GEM_SPEC.name.gsub(/-/, '_')
|
21
|
+
|
22
|
+
## ======================================================================
|
23
|
+
|
11
24
|
require 'rake/clean'
|
25
|
+
|
26
|
+
CLEAN.include('pkg')
|
27
|
+
CLOBBER.include('test/log')
|
28
|
+
CLOBBER.include('test/log.*')
|
29
|
+
|
30
|
+
## ======================================================================
|
31
|
+
|
12
32
|
require 'rake/extensiontask'
|
13
|
-
require 'rake/testtask'
|
14
33
|
|
15
|
-
|
34
|
+
Rake::ExtensionTask.new(EXT_NAME, GEM_SPEC) do |task|
|
35
|
+
task.source_pattern = '*.{c,h}'
|
36
|
+
end
|
37
|
+
|
38
|
+
## ======================================================================
|
39
|
+
|
40
|
+
require 'rake/testtask'
|
16
41
|
|
17
|
-
Rake::ExtensionTask.new("net_smb", GEMSPEC)
|
18
42
|
Rake::TestTask.new
|
19
43
|
|
20
|
-
|
44
|
+
## ======================================================================
|
45
|
+
|
46
|
+
task :default => [:compile]
|
21
47
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
48
|
+
task :clobber_pre do
|
49
|
+
## Fix directory permissions to be able to remove by task :clobber
|
50
|
+
Find.find(*Dir.glob("test/log/share"), *Dir.glob("test/log.*/share")) do |path|
|
51
|
+
if File.directory?(path)
|
52
|
+
File.chmod(0755, path)
|
53
|
+
end
|
26
54
|
end
|
27
|
-
cp "ext/#{EXT_PATH}/#{File.basename(EXT_PATH)}.so", "lib/#{EXT_PATH}.so"
|
28
55
|
end
|
29
56
|
|
30
|
-
task :
|
57
|
+
task :clobber => [:clobber_pre]
|
31
58
|
|
32
|
-
|
33
|
-
CLEAN.include('ext/**/Makefile')
|
34
|
-
CLEAN.include('lib/**/*.so')
|
35
|
-
CLOBBER.include('pkg/*')
|
36
|
-
CLOBBER.include('test/log')
|
37
|
-
CLOBBER.include('test/log.[0-9]')
|
59
|
+
task :test => "lib/#{EXT_NAME}.so"
|
38
60
|
|
data/ext/net_smb/depend
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
$(OBJS): rb_smb.h
|
data/ext/net_smb/rb_smb.h
CHANGED
@@ -51,6 +51,7 @@
|
|
51
51
|
#define RB_SMBFILE_BUFFER_SIZE 8192
|
52
52
|
|
53
53
|
typedef struct rb_smb_data RB_SMB_DATA;
|
54
|
+
typedef struct rb_smbstat_data RB_SMBSTAT_DATA;
|
54
55
|
typedef struct rb_smbfile_data RB_SMBFILE_DATA;
|
55
56
|
|
56
57
|
struct rb_smb_data {
|
@@ -60,6 +61,10 @@ struct rb_smb_data {
|
|
60
61
|
RB_SMBFILE_DATA *smbfile_data_list;
|
61
62
|
};
|
62
63
|
|
64
|
+
struct rb_smbstat_data {
|
65
|
+
struct stat stat;
|
66
|
+
};
|
67
|
+
|
63
68
|
struct rb_smbfile_data {
|
64
69
|
rb_encoding *enc;
|
65
70
|
VALUE smb_obj; /* Net::SMB object */
|
@@ -82,16 +87,27 @@ struct rb_smbfile_data {
|
|
82
87
|
RB_SMB_DATA *data; \
|
83
88
|
Data_Get_Struct(obj, RB_SMB_DATA, data);
|
84
89
|
|
90
|
+
#define RB_SMBSTAT_DATA_FROM_OBJ(obj, data) \
|
91
|
+
RB_SMBSTAT_DATA *data; \
|
92
|
+
Data_Get_Struct(obj, RB_SMBSTAT_DATA, data);
|
93
|
+
|
85
94
|
#define RB_SMBFILE_DATA_FROM_OBJ(obj, data) \
|
86
95
|
RB_SMBFILE_DATA *data; \
|
87
96
|
Data_Get_Struct(obj, RB_SMBFILE_DATA, data);
|
88
97
|
|
98
|
+
#define RB_SMBFILE_DATA_CLOSED(data) \
|
99
|
+
if ((data)->smbcfile == NULL) { \
|
100
|
+
rb_raise(rb_eIOError, "Closed Net::SMB::File stream"); \
|
101
|
+
}
|
102
|
+
|
89
103
|
extern VALUE rb_cSMB;
|
90
104
|
extern VALUE rb_eSMBError;
|
105
|
+
extern VALUE rb_cSMBStat;
|
91
106
|
extern VALUE rb_cSMBDir;
|
92
107
|
extern VALUE rb_cSMBDirEntry;
|
93
108
|
extern VALUE rb_cSMBFile;
|
94
109
|
|
110
|
+
void Init_net_smbstat(void);
|
95
111
|
void Init_net_smbdir(void);
|
96
112
|
void Init_net_smbdirentry(void);
|
97
113
|
void Init_net_smbfile(void);
|
data/ext/net_smb/smb.c
CHANGED
@@ -224,6 +224,18 @@ static VALUE rb_smb_auth_callback(int argc, VALUE* argv, VALUE self)
|
|
224
224
|
return Qnil;
|
225
225
|
}
|
226
226
|
|
227
|
+
static VALUE rb_smb_stat(VALUE self, VALUE url_obj)
|
228
|
+
{
|
229
|
+
VALUE args[2];
|
230
|
+
VALUE smbstat;
|
231
|
+
|
232
|
+
args[0] = self;
|
233
|
+
args[1] = url_obj;
|
234
|
+
smbstat = rb_class_new_instance(2, args, rb_cSMBStat);
|
235
|
+
|
236
|
+
return smbstat;
|
237
|
+
}
|
238
|
+
|
227
239
|
static VALUE rb_smb_opendir(VALUE self, VALUE url_obj)
|
228
240
|
{
|
229
241
|
RB_SMB_DATA_FROM_OBJ(self, data);
|
@@ -273,6 +285,7 @@ void Init_net_smb(void)
|
|
273
285
|
rb_define_method(rb_cSMB, "use_kerberos=", rb_smb_use_kerberos_set, 1);
|
274
286
|
rb_define_method(rb_cSMB, "auth_callback", rb_smb_auth_callback, -1);
|
275
287
|
rb_define_alias(rb_cSMB, "auth", "auth_callback");
|
288
|
+
rb_define_method(rb_cSMB, "stat", rb_smb_stat, 1);
|
276
289
|
rb_define_method(rb_cSMB, "opendir", rb_smb_opendir, 1);
|
277
290
|
rb_define_method(rb_cSMB, "open", rb_smb_open, -1);
|
278
291
|
|
@@ -306,6 +319,7 @@ void Init_net_smb(void)
|
|
306
319
|
smbc_init_context(smbcctx);
|
307
320
|
}
|
308
321
|
|
322
|
+
Init_net_smbstat();
|
309
323
|
Init_net_smbdir();
|
310
324
|
Init_net_smbdirentry();
|
311
325
|
Init_net_smbfile();
|
data/ext/net_smb/smbdir.c
CHANGED
@@ -109,8 +109,7 @@ static VALUE rb_smbdir_initialize(VALUE self, VALUE smb_obj, VALUE url_obj)
|
|
109
109
|
RB_SMB_DEBUG("smbcctx=%p smbcfile=%p\n", data->smbcctx, data->smbcfile);
|
110
110
|
|
111
111
|
if (rb_block_given_p()) {
|
112
|
-
rb_ensure(rb_yield, self, rb_smbdir_close, self);
|
113
|
-
return Qnil;
|
112
|
+
return rb_ensure(rb_yield, self, rb_smbdir_close, self);
|
114
113
|
}
|
115
114
|
|
116
115
|
return self;
|
@@ -133,6 +132,7 @@ static VALUE rb_smbdir_url(VALUE self)
|
|
133
132
|
static VALUE rb_smbdir_close(VALUE self)
|
134
133
|
{
|
135
134
|
RB_SMBFILE_DATA_FROM_OBJ(self, data);
|
135
|
+
RB_SMBFILE_DATA_CLOSED(data);
|
136
136
|
|
137
137
|
RB_SMB_DEBUG("data=%p smbcctx=%p smbcfile=%p\n", data, data->smbcctx, data->smbcfile);
|
138
138
|
|
@@ -141,9 +141,25 @@ static VALUE rb_smbdir_close(VALUE self)
|
|
141
141
|
return self;
|
142
142
|
}
|
143
143
|
|
144
|
+
#define rb_smbdir_closed_p_by_data(data) \
|
145
|
+
(((data)->smbcfile == NULL) ? Qtrue : Qfalse)
|
146
|
+
|
147
|
+
static VALUE rb_smbdir_closed_p(VALUE self)
|
148
|
+
{
|
149
|
+
RB_SMBFILE_DATA_FROM_OBJ(self, data);
|
150
|
+
|
151
|
+
return rb_smbdir_closed_p_by_data(data);
|
152
|
+
}
|
153
|
+
|
154
|
+
static VALUE rb_smbdir_stat(VALUE self)
|
155
|
+
{
|
156
|
+
return rb_class_new_instance(1, &self, rb_cSMBStat);
|
157
|
+
}
|
158
|
+
|
144
159
|
static VALUE rb_smbdir_tell(VALUE self)
|
145
160
|
{
|
146
161
|
RB_SMBFILE_DATA_FROM_OBJ(self, data);
|
162
|
+
RB_SMBFILE_DATA_CLOSED(data);
|
147
163
|
smbc_telldir_fn fn;
|
148
164
|
off_t offset;
|
149
165
|
|
@@ -163,6 +179,7 @@ static VALUE rb_smbdir_tell(VALUE self)
|
|
163
179
|
static VALUE rb_smbdir_seek(VALUE self, VALUE offset_num)
|
164
180
|
{
|
165
181
|
RB_SMBFILE_DATA_FROM_OBJ(self, data);
|
182
|
+
RB_SMBFILE_DATA_CLOSED(data);
|
166
183
|
smbc_lseekdir_fn fn;
|
167
184
|
off_t offset = (off_t)NUM2LONG(offset_num);
|
168
185
|
|
@@ -184,6 +201,7 @@ static VALUE rb_smbdir_rewind(VALUE self)
|
|
184
201
|
static VALUE rb_smbdir_read(VALUE self)
|
185
202
|
{
|
186
203
|
RB_SMBFILE_DATA_FROM_OBJ(self, data);
|
204
|
+
RB_SMBFILE_DATA_CLOSED(data);
|
187
205
|
smbc_readdir_fn fn;
|
188
206
|
struct smbc_dirent *smbcdent;
|
189
207
|
|
@@ -239,6 +257,8 @@ void Init_net_smbdir(void)
|
|
239
257
|
rb_define_method(rb_cSMBDir, "smb", rb_smbdir_smb, 0);
|
240
258
|
rb_define_method(rb_cSMBDir, "url", rb_smbdir_url, 0);
|
241
259
|
rb_define_method(rb_cSMBDir, "close", rb_smbdir_close, 0);
|
260
|
+
rb_define_method(rb_cSMBDir, "closed?", rb_smbdir_closed_p, 0);
|
261
|
+
rb_define_method(rb_cSMBDir, "stat", rb_smbdir_stat, 0);
|
242
262
|
rb_define_method(rb_cSMBDir, "tell", rb_smbdir_tell, 0);
|
243
263
|
rb_define_alias(rb_cSMBDir, "pos", "tell");
|
244
264
|
rb_define_method(rb_cSMBDir, "seek", rb_smbdir_seek, 1);
|
data/ext/net_smb/smbdirentry.c
CHANGED
@@ -21,10 +21,10 @@
|
|
21
21
|
|
22
22
|
VALUE rb_cSMBDirEntry;
|
23
23
|
|
24
|
-
VALUE sym_name;
|
25
|
-
VALUE sym_type;
|
26
|
-
VALUE sym_url;
|
27
|
-
VALUE sym_comment;
|
24
|
+
static VALUE sym_name;
|
25
|
+
static VALUE sym_type;
|
26
|
+
static VALUE sym_url;
|
27
|
+
static VALUE sym_comment;
|
28
28
|
|
29
29
|
/* ====================================================================== */
|
30
30
|
|
@@ -35,7 +35,7 @@ static VALUE rb_smbdirentry_initialize(VALUE self,
|
|
35
35
|
|
36
36
|
rb_hash_aset(self, sym_name, name_obj);
|
37
37
|
rb_hash_aset(self, sym_type, type_obj);
|
38
|
-
rb_hash_aset(self, sym_url,
|
38
|
+
rb_hash_aset(self, sym_url, url_obj);
|
39
39
|
rb_hash_aset(self, sym_comment, comment_obj);
|
40
40
|
|
41
41
|
return self;
|
data/ext/net_smb/smbfile.c
CHANGED
@@ -151,6 +151,8 @@ try:
|
|
151
151
|
data->eof = (read_size == 0);
|
152
152
|
}
|
153
153
|
|
154
|
+
static VALUE rb_smbfile_close(VALUE self);
|
155
|
+
|
154
156
|
static VALUE rb_smbfile_initialize(int argc, VALUE *argv, VALUE self)
|
155
157
|
{
|
156
158
|
RB_SMBFILE_DATA_FROM_OBJ(self, data);
|
@@ -185,6 +187,10 @@ static VALUE rb_smbfile_initialize(int argc, VALUE *argv, VALUE self)
|
|
185
187
|
|
186
188
|
rb_smbfile_open_by_data(data);
|
187
189
|
|
190
|
+
if (rb_block_given_p()) {
|
191
|
+
return rb_ensure(rb_yield, self, rb_smbfile_close, self);
|
192
|
+
}
|
193
|
+
|
188
194
|
return self;
|
189
195
|
}
|
190
196
|
|
@@ -210,6 +216,7 @@ static VALUE rb_smbfile_read_buffer_size(VALUE self)
|
|
210
216
|
static VALUE rb_smbfile_close(VALUE self)
|
211
217
|
{
|
212
218
|
RB_SMBFILE_DATA_FROM_OBJ(self, data);
|
219
|
+
RB_SMBFILE_DATA_CLOSED(data);
|
213
220
|
|
214
221
|
RB_SMB_DEBUG("data=%p smbcctx=%p smbcfile=%p\n", data, data->smbcctx, data->smbcfile);
|
215
222
|
|
@@ -218,18 +225,38 @@ static VALUE rb_smbfile_close(VALUE self)
|
|
218
225
|
return self;
|
219
226
|
}
|
220
227
|
|
221
|
-
|
228
|
+
#define rb_smbfile_closed_p_by_data(data) \
|
229
|
+
(((data)->smbcfile == NULL) ? Qtrue : Qfalse)
|
230
|
+
|
231
|
+
static VALUE rb_smbfile_closed_p(VALUE self)
|
222
232
|
{
|
223
233
|
RB_SMBFILE_DATA_FROM_OBJ(self, data);
|
224
234
|
|
235
|
+
return rb_smbfile_closed_p_by_data(data);
|
236
|
+
}
|
237
|
+
|
238
|
+
static VALUE rb_smbfile_stat(VALUE self)
|
239
|
+
{
|
240
|
+
return rb_class_new_instance(1, &self, rb_cSMBStat);
|
241
|
+
}
|
242
|
+
|
243
|
+
static VALUE rb_smbfile_pos(VALUE self)
|
244
|
+
{
|
245
|
+
RB_SMBFILE_DATA_FROM_OBJ(self, data);
|
246
|
+
RB_SMBFILE_DATA_CLOSED(data);
|
247
|
+
|
225
248
|
return SIZET2NUM(data->pos);
|
226
249
|
}
|
227
250
|
|
228
|
-
static VALUE rb_smbfile_seek(
|
251
|
+
static VALUE rb_smbfile_seek(int argc, VALUE *argv, VALUE self)
|
229
252
|
{
|
230
253
|
RB_SMBFILE_DATA_FROM_OBJ(self, data);
|
231
|
-
|
232
|
-
|
254
|
+
RB_SMBFILE_DATA_CLOSED(data);
|
255
|
+
|
256
|
+
VALUE whence_num;
|
257
|
+
rb_scan_args(argc, argv, "11", NULL, &whence_num);
|
258
|
+
off_t offset = NUM2OFFT(argv[0]);
|
259
|
+
int whence = NIL_P(whence_num) ? SEEK_SET : NUM2INT(whence_num);
|
233
260
|
|
234
261
|
switch (whence) {
|
235
262
|
case SEEK_SET:
|
@@ -255,14 +282,22 @@ static VALUE rb_smbfile_seek(VALUE self, VALUE offset_num, VALUE whence_num)
|
|
255
282
|
return self;
|
256
283
|
}
|
257
284
|
|
285
|
+
static VALUE rb_smbfile_pos_set(VALUE self, VALUE offset)
|
286
|
+
{
|
287
|
+
return rb_smbfile_seek(1, &offset, self);
|
288
|
+
}
|
289
|
+
|
258
290
|
static VALUE rb_smbfile_rewind(VALUE self)
|
259
291
|
{
|
260
|
-
|
292
|
+
VALUE argv = OFFT2NUM(0);
|
293
|
+
|
294
|
+
return rb_smbfile_seek(1, &argv, self);
|
261
295
|
}
|
262
296
|
|
263
297
|
static VALUE rb_smbfile_eof_p(VALUE self)
|
264
298
|
{
|
265
299
|
RB_SMBFILE_DATA_FROM_OBJ(self, data);
|
300
|
+
RB_SMBFILE_DATA_CLOSED(data);
|
266
301
|
|
267
302
|
if (data->buffer_used_size - data->buffer_pos > 0) {
|
268
303
|
/* Remained data exist in buffer */
|
@@ -290,6 +325,7 @@ static void rb_smbfile_readable_p_by_data(RB_SMBFILE_DATA *data)
|
|
290
325
|
static VALUE rb_smbfile_read(int argc, VALUE *argv, VALUE self)
|
291
326
|
{
|
292
327
|
RB_SMBFILE_DATA_FROM_OBJ(self, data);
|
328
|
+
RB_SMBFILE_DATA_CLOSED(data);
|
293
329
|
ssize_t req_read_size;
|
294
330
|
VALUE str = rb_str_new2("");
|
295
331
|
|
@@ -350,11 +386,15 @@ void Init_net_smbfile(void)
|
|
350
386
|
rb_define_method(rb_cSMBFile, "url", rb_smbfile_url, 0);
|
351
387
|
rb_define_method(rb_cSMBFile, "read_buffer_size", rb_smbfile_read_buffer_size, 0);
|
352
388
|
rb_define_method(rb_cSMBFile, "close", rb_smbfile_close, 0);
|
353
|
-
rb_define_method(rb_cSMBFile, "
|
354
|
-
|
355
|
-
rb_define_method(rb_cSMBFile, "
|
389
|
+
rb_define_method(rb_cSMBFile, "closed?", rb_smbfile_closed_p, 0);
|
390
|
+
rb_define_method(rb_cSMBFile, "stat", rb_smbfile_stat, 0);
|
391
|
+
rb_define_method(rb_cSMBFile, "pos", rb_smbfile_pos, 0);
|
392
|
+
rb_define_alias(rb_cSMBFile, "tell", "pos");
|
393
|
+
rb_define_method(rb_cSMBFile, "seek", rb_smbfile_seek, -1);
|
394
|
+
rb_define_method(rb_cSMBFile, "pos=", rb_smbfile_pos_set, 1);
|
356
395
|
rb_define_method(rb_cSMBFile, "rewind", rb_smbfile_rewind, 0);
|
357
396
|
rb_define_method(rb_cSMBFile, "eof?", rb_smbfile_eof_p, 0);
|
397
|
+
rb_define_alias(rb_cSMBFile, "eof", "eof?");
|
358
398
|
rb_define_method(rb_cSMBFile, "read", rb_smbfile_read, -1);
|
359
399
|
}
|
360
400
|
|
@@ -0,0 +1,200 @@
|
|
1
|
+
/*
|
2
|
+
* Ruby/Net::SMB - SMB/CIFS client (Samba libsmbclient binding) for Ruby
|
3
|
+
* Net::SMB::Stat class
|
4
|
+
* Copyright (C) 2012 SATOH Fumiyas @ OSS Technology Corp., Japan
|
5
|
+
*
|
6
|
+
* This program is free software; you can redistribute it and/or modify
|
7
|
+
* it under the terms of the GNU General Public License as published by
|
8
|
+
* the Free Software Foundation; either version 3 of the License, or
|
9
|
+
* (at your option) any later version.
|
10
|
+
*
|
11
|
+
* This program is distributed in the hope that it will be useful,
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
* GNU General Public License for more details.
|
15
|
+
*
|
16
|
+
* You should have received a copy of the GNU General Public License
|
17
|
+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
*/
|
19
|
+
|
20
|
+
#include "rb_smb.h"
|
21
|
+
|
22
|
+
#ifndef NUM2DEVT
|
23
|
+
# define NUM2DEVT(v) NUM2UINT(v)
|
24
|
+
#endif
|
25
|
+
#ifndef DEVT2NUM
|
26
|
+
# define DEVT2NUM(v) UINT2NUM(v)
|
27
|
+
#endif
|
28
|
+
|
29
|
+
VALUE rb_cSMBStat;
|
30
|
+
|
31
|
+
static ID id_to_s;
|
32
|
+
|
33
|
+
/* ====================================================================== */
|
34
|
+
|
35
|
+
static void rb_smbstat_data_free(RB_SMBSTAT_DATA *data)
|
36
|
+
{
|
37
|
+
ruby_xfree(data);
|
38
|
+
}
|
39
|
+
|
40
|
+
static VALUE rb_smbstat_data_alloc(VALUE klass)
|
41
|
+
{
|
42
|
+
RB_SMBSTAT_DATA *data = ALLOC(RB_SMBSTAT_DATA);
|
43
|
+
|
44
|
+
memset(data, 0, sizeof(*data));
|
45
|
+
|
46
|
+
return Data_Wrap_Struct(klass, NULL, rb_smbstat_data_free, data);
|
47
|
+
}
|
48
|
+
|
49
|
+
static VALUE rb_smbstat_initialize(int argc, VALUE *argv, VALUE self)
|
50
|
+
{
|
51
|
+
RB_SMBSTAT_DATA_FROM_OBJ(self, data);
|
52
|
+
VALUE smb_or_file_obj;
|
53
|
+
VALUE url_obj;
|
54
|
+
|
55
|
+
rb_scan_args(argc, argv, "11", &smb_or_file_obj, &url_obj);
|
56
|
+
|
57
|
+
if (rb_obj_is_kind_of(smb_or_file_obj, rb_cSMB)) {
|
58
|
+
RB_SMB_DATA_FROM_OBJ(smb_or_file_obj, smb_data);
|
59
|
+
|
60
|
+
if (rb_obj_is_kind_of(url_obj, rb_cString)) {
|
61
|
+
/* OK */
|
62
|
+
}
|
63
|
+
else if (rb_respond_to(url_obj, id_to_s)) {
|
64
|
+
url_obj = rb_funcall(url_obj, id_to_s, 0);
|
65
|
+
}
|
66
|
+
else {
|
67
|
+
rb_raise(rb_eTypeError, "String was expected");
|
68
|
+
}
|
69
|
+
|
70
|
+
const char *url = StringValueCStr(url_obj);
|
71
|
+
smbc_stat_fn fn = smbc_getFunctionStat(smb_data->smbcctx);
|
72
|
+
if ((*fn)(smb_data->smbcctx, url, &data->stat)) {
|
73
|
+
rb_sys_fail("SMBC_stat_ctx() failed");
|
74
|
+
}
|
75
|
+
}
|
76
|
+
else if (rb_obj_is_kind_of(smb_or_file_obj, rb_cSMBFile)) {
|
77
|
+
RB_SMBFILE_DATA_FROM_OBJ(smb_or_file_obj, smbfile_data);
|
78
|
+
smbc_fstat_fn fn = smbc_getFunctionFstat(smbfile_data->smbcctx);
|
79
|
+
|
80
|
+
if ((*fn)(smbfile_data->smbcctx, smbfile_data->smbcfile, &data->stat)) {
|
81
|
+
rb_sys_fail("SMBC_fstat_ctx() failed");
|
82
|
+
}
|
83
|
+
}
|
84
|
+
else if (rb_obj_is_kind_of(smb_or_file_obj, rb_cSMBDir)) {
|
85
|
+
RB_SMBFILE_DATA_FROM_OBJ(smb_or_file_obj, smbfile_data);
|
86
|
+
#if 0
|
87
|
+
/*
|
88
|
+
* SMBC_fstatdir_ctx() does nothing. See source/libsmb/libsmb_dir.c in
|
89
|
+
* Samba source tree.
|
90
|
+
*/
|
91
|
+
smbc_fstatdir_fn fn = smbc_getFunctionFstatdir(smbfile_data->smbcctx);
|
92
|
+
|
93
|
+
if ((*fn)(smbfile_data->smbcctx, smbfile_data->smbcfile, &data->stat)) {
|
94
|
+
rb_sys_fail("SMBC_fstatdir_ctx() failed");
|
95
|
+
}
|
96
|
+
#else
|
97
|
+
smbc_stat_fn fn = smbc_getFunctionStat(smbfile_data->smbcctx);
|
98
|
+
if ((*fn)(smbfile_data->smbcctx, smbfile_data->url, &data->stat)) {
|
99
|
+
rb_sys_fail("SMBC_stat_ctx() failed");
|
100
|
+
}
|
101
|
+
#endif
|
102
|
+
}
|
103
|
+
else {
|
104
|
+
rb_raise(rb_eTypeError, "Net::SMB, Net::SMB::Dir or Net::SMB::File was expected");
|
105
|
+
}
|
106
|
+
|
107
|
+
return self;
|
108
|
+
}
|
109
|
+
|
110
|
+
static VALUE rb_smbstat_dev(VALUE self)
|
111
|
+
{
|
112
|
+
RB_SMBSTAT_DATA_FROM_OBJ(self, data);
|
113
|
+
|
114
|
+
return DEVT2NUM(data->stat.st_dev);
|
115
|
+
}
|
116
|
+
|
117
|
+
static VALUE rb_smbstat_ino(VALUE self)
|
118
|
+
{
|
119
|
+
RB_SMBSTAT_DATA_FROM_OBJ(self, data);
|
120
|
+
|
121
|
+
return ULL2NUM(data->stat.st_ino);
|
122
|
+
}
|
123
|
+
|
124
|
+
static VALUE rb_smbstat_mode(VALUE self)
|
125
|
+
{
|
126
|
+
RB_SMBSTAT_DATA_FROM_OBJ(self, data);
|
127
|
+
|
128
|
+
return UINT2NUM(data->stat.st_mode);
|
129
|
+
}
|
130
|
+
|
131
|
+
static VALUE rb_smbstat_nlink(VALUE self)
|
132
|
+
{
|
133
|
+
RB_SMBSTAT_DATA_FROM_OBJ(self, data);
|
134
|
+
|
135
|
+
return ULL2NUM(data->stat.st_nlink);
|
136
|
+
}
|
137
|
+
|
138
|
+
static VALUE rb_smbstat_uid(VALUE self)
|
139
|
+
{
|
140
|
+
RB_SMBSTAT_DATA_FROM_OBJ(self, data);
|
141
|
+
|
142
|
+
return UIDT2NUM(data->stat.st_uid);
|
143
|
+
}
|
144
|
+
|
145
|
+
static VALUE rb_smbstat_gid(VALUE self)
|
146
|
+
{
|
147
|
+
RB_SMBSTAT_DATA_FROM_OBJ(self, data);
|
148
|
+
|
149
|
+
return GIDT2NUM(data->stat.st_gid);
|
150
|
+
}
|
151
|
+
|
152
|
+
static VALUE rb_smbstat_size(VALUE self)
|
153
|
+
{
|
154
|
+
RB_SMBSTAT_DATA_FROM_OBJ(self, data);
|
155
|
+
|
156
|
+
return OFFT2NUM(data->stat.st_size);
|
157
|
+
}
|
158
|
+
|
159
|
+
static VALUE rb_smbstat_atime(VALUE self)
|
160
|
+
{
|
161
|
+
RB_SMBSTAT_DATA_FROM_OBJ(self, data);
|
162
|
+
|
163
|
+
return rb_time_new(data->stat.st_atime, 0);
|
164
|
+
}
|
165
|
+
|
166
|
+
static VALUE rb_smbstat_mtime(VALUE self)
|
167
|
+
{
|
168
|
+
RB_SMBSTAT_DATA_FROM_OBJ(self, data);
|
169
|
+
|
170
|
+
return rb_time_new(data->stat.st_mtime, 0);
|
171
|
+
}
|
172
|
+
|
173
|
+
static VALUE rb_smbstat_ctime(VALUE self)
|
174
|
+
{
|
175
|
+
RB_SMBSTAT_DATA_FROM_OBJ(self, data);
|
176
|
+
|
177
|
+
return rb_time_new(data->stat.st_ctime, 0);
|
178
|
+
}
|
179
|
+
|
180
|
+
/* ====================================================================== */
|
181
|
+
|
182
|
+
void Init_net_smbstat(void)
|
183
|
+
{
|
184
|
+
rb_cSMBStat = rb_define_class_under(rb_cSMB, "Stat", rb_cObject);
|
185
|
+
rb_define_alloc_func(rb_cSMBStat, rb_smbstat_data_alloc);
|
186
|
+
rb_define_method(rb_cSMBStat, "initialize", rb_smbstat_initialize, -1);
|
187
|
+
rb_define_method(rb_cSMBStat, "dev", rb_smbstat_dev, 0);
|
188
|
+
rb_define_method(rb_cSMBStat, "ino", rb_smbstat_ino, 0);
|
189
|
+
rb_define_method(rb_cSMBStat, "nlink", rb_smbstat_nlink, 0);
|
190
|
+
rb_define_method(rb_cSMBStat, "mode", rb_smbstat_mode, 0);
|
191
|
+
rb_define_method(rb_cSMBStat, "uid", rb_smbstat_uid, 0);
|
192
|
+
rb_define_method(rb_cSMBStat, "gid", rb_smbstat_gid, 0);
|
193
|
+
rb_define_method(rb_cSMBStat, "size", rb_smbstat_size, 0);
|
194
|
+
rb_define_method(rb_cSMBStat, "atime", rb_smbstat_atime, 0);
|
195
|
+
rb_define_method(rb_cSMBStat, "mtime", rb_smbstat_mtime, 0);
|
196
|
+
rb_define_method(rb_cSMBStat, "ctime", rb_smbstat_ctime, 0);
|
197
|
+
|
198
|
+
id_to_s = rb_intern("to_s");
|
199
|
+
}
|
200
|
+
|
data/lib/net/smb/version.rb
CHANGED
data/net-smb.gemspec
CHANGED
data/test/etc/smb.conf
CHANGED
data/test/test_net_smb.rb
CHANGED
@@ -8,106 +8,107 @@ require 'etc'
|
|
8
8
|
module Net
|
9
9
|
|
10
10
|
class SMBTest < Test::Unit::TestCase
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
File.rename(logdir_a, logdir_b)
|
63
|
-
end
|
11
|
+
@@test_dir = ENV['TEST_DIR'] = "#{Dir.getwd}/test"
|
12
|
+
@@username = Etc.getpwuid(Process.uid)['name']
|
13
|
+
@@password = 'password'
|
14
|
+
|
15
|
+
@@smb_conf = ENV['TEST_SMB_CONF'] ||= @@test_dir + "/etc/smb.conf"
|
16
|
+
@@smbd = ENV['TEST_SMBD'] ||= "smbd"
|
17
|
+
@@pdbedit = ENV['TEST_PDBEDIT'] ||= "pdbedit"
|
18
|
+
@@smbstatus = ENV['TEST_SMBSTATUS'] ||= "smbstatus"
|
19
|
+
@@samba_debug_level = ENV['TEST_SAMBA_DEBUGLEVEL'] ||= "10"
|
20
|
+
@@samba_log_dir = ENV['TEST_SAMBA_LOG_DIR'] ||= @@test_dir + "/log"
|
21
|
+
@@samba_var_dir = ENV['TEST_SAMBA_VAR_DIR'] ||= @@samba_log_dir + "/var"
|
22
|
+
@@share_dir = ENV['TEST_SHARE_DIR'] ||= @@samba_log_dir + "/share"
|
23
|
+
|
24
|
+
@@share_private = "smb://localhost/private"
|
25
|
+
@@share_public = "smb://localhost/public"
|
26
|
+
@@dir_noexist = "dir.noexist"
|
27
|
+
@@dir_writeable = "dir.writeable"
|
28
|
+
@@dir_writeable_m = "ディレクトリ.writeable"
|
29
|
+
@@dirs_writeable = [@@dir_writeable, @@dir_writeable_m]
|
30
|
+
@@dir_readable = "dir.readable"
|
31
|
+
@@dirs_readable = [@@dir_readable]
|
32
|
+
@@dir_noaccess = "dir.noaccess"
|
33
|
+
@@dirs_noaccess = [@@dir_noaccess]
|
34
|
+
@@dirs = [".", ".."] + @@dirs_readable + @@dirs_writeable + @@dirs_noaccess
|
35
|
+
@@file_noexist = "file.noexist"
|
36
|
+
@@file_writeable = "file.writeable"
|
37
|
+
@@file_writeable_m = "ファイル.writeable"
|
38
|
+
@@files_writeable = [@@file_writeable, @@file_writeable_m]
|
39
|
+
@@file_readable = "file.readable"
|
40
|
+
@@files_readable = [@@file_readable]
|
41
|
+
@@file_noaccess = "file.noaccess"
|
42
|
+
@@files_noaccess = [@@file_noaccess]
|
43
|
+
@@file_large = "file.large"
|
44
|
+
@@files_misc = [@@file_large]
|
45
|
+
@@files = @@files_readable + @@files_writeable + @@files_noaccess + @@files_misc
|
46
|
+
|
47
|
+
ENV['SMB_CONF_PATH'] = nil;
|
48
|
+
ENV['LIBSMB_PROG'] ||= @@test_dir + "/bin/smbd.wrapper"
|
49
|
+
|
50
|
+
## Rotate log directory
|
51
|
+
if File.exist?(@@samba_log_dir + '.9')
|
52
|
+
system('/bin/rm', '-rf', @@samba_log_dir + '.9');
|
53
|
+
end
|
54
|
+
if File.exist?(@@samba_log_dir)
|
55
|
+
File.rename(@@samba_log_dir, @@samba_log_dir + '.0')
|
56
|
+
end
|
57
|
+
9.downto(1) do |i|
|
58
|
+
logdir_a = @@samba_log_dir + '.' + (i-1).to_s
|
59
|
+
logdir_b = @@samba_log_dir + '.' + i.to_s
|
60
|
+
if File.exist?(logdir_a)
|
61
|
+
File.rename(logdir_a, logdir_b)
|
64
62
|
end
|
63
|
+
end
|
65
64
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
end
|
65
|
+
Dir.mkdir(@@samba_log_dir, 0750)
|
66
|
+
Dir.mkdir(@@samba_var_dir, 0750)
|
67
|
+
Dir.mkdir(@@share_dir, 0750)
|
68
|
+
@@dirs_readable.each do |dname|
|
69
|
+
Dir.mkdir(@@share_dir + '/' + dname, 0550)
|
70
|
+
end
|
71
|
+
@@dirs_writeable.each do |dname|
|
72
|
+
Dir.mkdir(@@share_dir + '/' + dname, 0750)
|
73
|
+
end
|
74
|
+
@@dirs_noaccess.each do |dname|
|
75
|
+
Dir.mkdir(@@share_dir + '/' + dname, 0000)
|
76
|
+
end
|
77
|
+
@@files_readable.each do |fname|
|
78
|
+
File.open(@@share_dir + '/' + fname, "wb", 0440) do |file|
|
79
|
+
file.write(fname)
|
82
80
|
end
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
81
|
+
end
|
82
|
+
@@files_writeable.each do |fname|
|
83
|
+
File.open(@@share_dir + '/' + fname, "wb", 0660) do |file|
|
84
|
+
file.write(fname)
|
87
85
|
end
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
86
|
+
end
|
87
|
+
@@files_noaccess.each do |fname|
|
88
|
+
File.open(@@share_dir + '/' + fname, "wb", 0000) do |file|
|
89
|
+
file.write(fname)
|
92
90
|
end
|
91
|
+
end
|
93
92
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
end
|
93
|
+
File.open(@@share_dir + '/' + @@file_large, "wb", 0660) do |file|
|
94
|
+
random_chars = (0...100).map { rand(256).chr }.join("")
|
95
|
+
100000.times do |n|
|
96
|
+
file.write(random_chars)
|
99
97
|
end
|
98
|
+
end
|
100
99
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
100
|
+
pdbedit_r, pdbedit_w = IO.pipe
|
101
|
+
pdbedit_pid = Kernel.spawn(
|
102
|
+
@@pdbedit, "--configfile", @@smb_conf, "--create", "--password-from-stdin", @@username,
|
103
|
+
:in => pdbedit_r,
|
104
|
+
[:out, :err] => [@@samba_log_dir + '/pdbedit.log', 'w'],
|
105
|
+
)
|
106
|
+
pdbedit_r.close
|
107
|
+
pdbedit_w.print(@@password, "\n")
|
108
|
+
pdbedit_w.print(@@password, "\n")
|
109
|
+
pdbedit_w.close
|
110
|
+
|
111
|
+
def setup
|
111
112
|
end
|
112
113
|
|
113
114
|
def teardown
|
@@ -116,9 +117,9 @@ class SMBTest < Test::Unit::TestCase
|
|
116
117
|
def smbstatus
|
117
118
|
smbstatus_r, smbstatus_w = IO.pipe
|
118
119
|
smbstatus_pid = Kernel.spawn(
|
119
|
-
|
120
|
+
@@smbstatus, "--configfile", @@smb_conf, "--shares",
|
120
121
|
:out => smbstatus_w,
|
121
|
-
:err => [
|
122
|
+
:err => [@@samba_log_dir + '/smbstatus.log', 'w+'],
|
122
123
|
)
|
123
124
|
smbstatus_w.close
|
124
125
|
smbstatus_r.readline
|
@@ -131,7 +132,7 @@ class SMBTest < Test::Unit::TestCase
|
|
131
132
|
def smb
|
132
133
|
smb = Net::SMB.new
|
133
134
|
smb.auth_callback {|server, share|
|
134
|
-
[
|
135
|
+
[@@username, @@password]
|
135
136
|
}
|
136
137
|
|
137
138
|
return smb
|
@@ -140,27 +141,27 @@ class SMBTest < Test::Unit::TestCase
|
|
140
141
|
def test_auth
|
141
142
|
smb = Net::SMB.new
|
142
143
|
smb.auth_callback {|server, share|
|
143
|
-
[
|
144
|
+
[@@username, @@password]
|
144
145
|
}
|
145
146
|
assert_nothing_raised do
|
146
|
-
smbdir = smb.opendir(
|
147
|
+
smbdir = smb.opendir(@@share_private)
|
147
148
|
smbdir.close
|
148
149
|
end
|
149
150
|
|
150
151
|
smb = Net::SMB.new
|
151
152
|
smb.auth_callback {|server, share|
|
152
|
-
[
|
153
|
+
[@@username, 'invalid-password']
|
153
154
|
}
|
154
155
|
assert_raise(Errno::EPERM) do
|
155
|
-
smb.opendir(
|
156
|
+
smb.opendir(@@share_private)
|
156
157
|
end
|
157
158
|
|
158
159
|
smb = Net::SMB.new
|
159
160
|
smb.auth_callback {|server, share|
|
160
|
-
['invalid-user',
|
161
|
+
['invalid-user', @@password]
|
161
162
|
}
|
162
163
|
assert_raise(Errno::EACCES) do
|
163
|
-
smb.opendir(
|
164
|
+
smb.opendir(@@share_private)
|
164
165
|
end
|
165
166
|
|
166
167
|
smb = Net::SMB.new
|
@@ -168,61 +169,74 @@ class SMBTest < Test::Unit::TestCase
|
|
168
169
|
'blah-blah'
|
169
170
|
}
|
170
171
|
assert_raise(TypeError) do
|
171
|
-
smb.opendir(
|
172
|
+
smb.opendir(@@share_private)
|
172
173
|
end
|
173
174
|
|
174
175
|
smb = Net::SMB.new
|
175
176
|
smb.auth_callback {|server, share|
|
176
|
-
[
|
177
|
+
[@@username]
|
177
178
|
}
|
178
179
|
assert_raise(ArgumentError) do
|
179
|
-
smb.opendir(
|
180
|
+
smb.opendir(@@share_private)
|
180
181
|
end
|
181
182
|
end
|
182
183
|
|
183
184
|
def test_dir_open_close
|
184
185
|
smb = self.smb
|
185
186
|
|
186
|
-
smbdir = smb.opendir(
|
187
|
+
smbdir = smb.opendir(@@share_public)
|
187
188
|
assert_equal(smb.object_id, smbdir.smb.object_id)
|
188
|
-
assert_equal(
|
189
|
+
assert_equal(@@share_public, smbdir.url)
|
190
|
+
|
191
|
+
assert_equal(false, smbdir.closed?)
|
189
192
|
smbdir.close
|
193
|
+
assert_equal(true, smbdir.closed?)
|
194
|
+
|
190
195
|
assert_raise(IOError) do
|
191
196
|
smbdir.close
|
192
197
|
end
|
198
|
+
assert_raise(IOError) do
|
199
|
+
smbdir.read
|
200
|
+
end
|
201
|
+
assert_raise(IOError) do
|
202
|
+
smbdir.pos
|
203
|
+
end
|
204
|
+
assert_raise(IOError) do
|
205
|
+
smbdir.seek(0)
|
206
|
+
end
|
193
207
|
|
194
208
|
assert_raise(Errno::ENOENT) do
|
195
|
-
smbdir = smb.opendir(
|
209
|
+
smbdir = smb.opendir(@@share_public + '/' + @@dir_noexist)
|
196
210
|
end
|
197
211
|
assert_raise(Errno::EACCES) do
|
198
|
-
smbdir = smb.opendir(
|
212
|
+
smbdir = smb.opendir(@@share_public + '/' + @@dir_noaccess)
|
199
213
|
end
|
200
214
|
## Errno::ENOENT is not expected, but Samba 3.5 and 3.6 has a bug:
|
201
215
|
## https://bugzilla.samba.org/show_bug.cgi?id=9021
|
202
216
|
assert_raise(Errno::ENOTDIR, Errno::ENOENT) do
|
203
|
-
smbdir = smb.opendir(
|
217
|
+
smbdir = smb.opendir(@@share_public + '/' + @@file_writeable)
|
204
218
|
end
|
205
219
|
end ## test_dir_open_close
|
206
220
|
|
207
221
|
def test_dir_read
|
208
222
|
smb = self.smb
|
209
|
-
dent_names_all = [
|
223
|
+
dent_names_all = [*@@dirs, *@@files]
|
210
224
|
|
211
|
-
smbdir = smb.opendir(
|
225
|
+
smbdir = smb.opendir(@@share_private)
|
212
226
|
dent_names = dent_names_all.clone
|
213
227
|
while dent = smbdir.read
|
214
228
|
assert_equal(dent.name, dent_names.delete(dent.name),
|
215
229
|
"Unexpected directory entry: #{dent.name}")
|
216
|
-
if
|
217
|
-
|
218
|
-
elsif
|
219
|
-
|
230
|
+
if @@dirs.include?(dent.name)
|
231
|
+
assert_equal(true, dent.dir?)
|
232
|
+
elsif @@files.include?(dent.name)
|
233
|
+
assert_equal(true, dent.file?)
|
220
234
|
end
|
221
235
|
end
|
222
236
|
assert_empty(dent_names)
|
223
237
|
smbdir.close
|
224
238
|
|
225
|
-
smb.opendir(
|
239
|
+
smb.opendir(@@share_public) do |smbdir|
|
226
240
|
dent_names = dent_names_all.clone
|
227
241
|
while dent = smbdir.read
|
228
242
|
assert_equal(dent.name, dent_names.delete(dent.name),
|
@@ -234,9 +248,9 @@ class SMBTest < Test::Unit::TestCase
|
|
234
248
|
|
235
249
|
def test_dir_seek
|
236
250
|
smb = self.smb
|
237
|
-
dent_names_all = [
|
251
|
+
dent_names_all = [*@@dirs, *@@files]
|
238
252
|
|
239
|
-
smbdir = smb.opendir(
|
253
|
+
smbdir = smb.opendir(@@share_private)
|
240
254
|
|
241
255
|
smbdir_pos_all = Array.new
|
242
256
|
fname_by_pos = Hash.new
|
@@ -285,27 +299,27 @@ class SMBTest < Test::Unit::TestCase
|
|
285
299
|
|
286
300
|
def test_dir_enum
|
287
301
|
smb = self.smb
|
288
|
-
dent_names_all = [
|
302
|
+
dent_names_all = [*@@dirs, *@@files]
|
289
303
|
|
290
|
-
smbdir = smb.opendir(
|
304
|
+
smbdir = smb.opendir(@@share_private)
|
291
305
|
dent_names = dent_names_all.clone
|
292
306
|
smbdir.each do |dent|
|
293
|
-
|
307
|
+
assert_equal(dent.name, dent_names.delete(dent.name))
|
294
308
|
end
|
295
309
|
assert_empty(dent_names)
|
296
310
|
smbdir.close
|
297
311
|
|
298
|
-
smbdir = smb.opendir(
|
312
|
+
smbdir = smb.opendir(@@share_private)
|
299
313
|
dent_names = dent_names_all.clone
|
300
314
|
smbdir.read
|
301
315
|
smbdir.read
|
302
316
|
smbdir.each do |dent|
|
303
|
-
|
317
|
+
assert_equal(dent.name, dent_names.delete(dent.name))
|
304
318
|
end
|
305
319
|
assert_empty(dent_names)
|
306
320
|
smbdir.close
|
307
321
|
|
308
|
-
smbdir = smb.opendir(
|
322
|
+
smbdir = smb.opendir(@@share_private)
|
309
323
|
dent_names = dent_names_all.clone
|
310
324
|
smbdir_enum = smbdir.each
|
311
325
|
dent_names.size.times do |n|
|
@@ -320,11 +334,92 @@ class SMBTest < Test::Unit::TestCase
|
|
320
334
|
smbdir.close
|
321
335
|
end ## test_dir_enum
|
322
336
|
|
337
|
+
def file_time2libsmb_time(file_time)
|
338
|
+
## Discard fractional seconds
|
339
|
+
smb_time = Time.at(file_time.to_i)
|
340
|
+
## Round up if fractional seconds is greater than 0.5
|
341
|
+
smb_time += 1 if (file_time - smb_time >= 0.5)
|
342
|
+
return smb_time
|
343
|
+
end
|
344
|
+
|
345
|
+
def test_smb_stat
|
346
|
+
smb = self.smb
|
347
|
+
|
348
|
+
smb.opendir(@@share_public) do |smbdir|
|
349
|
+
while dent = smbdir.read
|
350
|
+
next if (dent.name =~ /^\.\.?$/)
|
351
|
+
|
352
|
+
smb_stat = smb.stat(dent.url)
|
353
|
+
file_stat = File.stat(@@share_dir + '/' + dent.name)
|
354
|
+
|
355
|
+
assert_kind_of(Integer, smb_stat.dev, "Net::SMB::Stat#dev #{dent.name}")
|
356
|
+
assert_kind_of(Integer, smb_stat.ino, "Net::SMB::Stat#ino #{dent.name}")
|
357
|
+
assert_kind_of(Integer, smb_stat.nlink, "Net::SMB::Stat#nlink #{dent.name}")
|
358
|
+
#assert_equal(file_stat.mode, smb_stat.mode, "Net::SMB::Stat#mode #{dent.name}")
|
359
|
+
assert_equal(file_stat.uid, smb_stat.uid, "Net::SMB::Stat#uid #{dent.name}")
|
360
|
+
assert_equal(file_stat.gid, smb_stat.gid, "Net::SMB::Stat#gid #{dent.name}")
|
361
|
+
if (dent.dir?)
|
362
|
+
assert_equal(0, smb_stat.size, "Net::SMB::Stat#size #{dent.name}")
|
363
|
+
else
|
364
|
+
assert_equal(file_stat.size, smb_stat.size, "Net::SMB::Stat#size #{dent.name}")
|
365
|
+
end
|
366
|
+
assert_equal(file_time2libsmb_time(file_stat.atime), smb_stat.atime,
|
367
|
+
"Net::SMB::Stat#atime #{dent.name}")
|
368
|
+
assert_equal(file_time2libsmb_time(file_stat.mtime), smb_stat.mtime,
|
369
|
+
"Net::SMB::Stat#mtime #{dent.name}")
|
370
|
+
assert_equal(file_time2libsmb_time(file_stat.ctime), smb_stat.ctime,
|
371
|
+
"Net::SMB::Stat#ctime #{dent.name}")
|
372
|
+
end
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
def test_smbfile_stat
|
377
|
+
smb = self.smb
|
378
|
+
|
379
|
+
smb.opendir(@@share_public) do |smbdir|
|
380
|
+
while dent = smbdir.read
|
381
|
+
next if (dent.name =~ /^\.\.?$/)
|
382
|
+
next if (dent.name =~ /\.noaccess$/)
|
383
|
+
|
384
|
+
smb_stat = nil
|
385
|
+
if (dent.dir?)
|
386
|
+
smb.opendir(dent.url) do |smb_dir|
|
387
|
+
smb_stat = smb_dir.stat
|
388
|
+
end
|
389
|
+
else
|
390
|
+
smb.open(dent.url) do |smb_file|
|
391
|
+
smb_stat = smb_file.stat
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
file_stat = File.stat(@@share_dir + '/' + dent.name)
|
396
|
+
|
397
|
+
assert_kind_of(Integer, smb_stat.dev, "Net::SMB::Stat#dev #{dent.name}")
|
398
|
+
assert_kind_of(Integer, smb_stat.ino, "Net::SMB::Stat#ino #{dent.name}")
|
399
|
+
assert_kind_of(Integer, smb_stat.nlink, "Net::SMB::Stat#nlink #{dent.name}")
|
400
|
+
#assert_equal(file_stat.mode, smb_stat.mode, "Net::SMB::Stat#mode #{dent.name}")
|
401
|
+
assert_equal(file_stat.uid, smb_stat.uid, "Net::SMB::Stat#uid #{dent.name}")
|
402
|
+
assert_equal(file_stat.gid, smb_stat.gid, "Net::SMB::Stat#gid #{dent.name}")
|
403
|
+
if (dent.dir?)
|
404
|
+
assert_equal(0, smb_stat.size, "Net::SMB::Stat#size #{dent.name}")
|
405
|
+
else
|
406
|
+
assert_equal(file_stat.size, smb_stat.size, "Net::SMB::Stat#size #{dent.name}")
|
407
|
+
end
|
408
|
+
assert_equal(file_time2libsmb_time(file_stat.atime), smb_stat.atime,
|
409
|
+
"Net::SMB::Stat#atime #{dent.name}")
|
410
|
+
assert_equal(file_time2libsmb_time(file_stat.mtime), smb_stat.mtime,
|
411
|
+
"Net::SMB::Stat#mtime #{dent.name}")
|
412
|
+
assert_equal(file_time2libsmb_time(file_stat.ctime), smb_stat.ctime,
|
413
|
+
"Net::SMB::Stat#ctime #{dent.name}")
|
414
|
+
end
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
323
418
|
def test_file_open_read_close
|
324
419
|
smb = self.smb
|
325
420
|
|
326
|
-
|
327
|
-
url =
|
421
|
+
@@files_readable.each do |filename|
|
422
|
+
url = @@share_public + '/' + filename
|
328
423
|
smbfile = smb.open(url)
|
329
424
|
|
330
425
|
assert_equal(url, smbfile.url)
|
@@ -333,21 +428,35 @@ class SMBTest < Test::Unit::TestCase
|
|
333
428
|
smbfile.read(-1)
|
334
429
|
end
|
335
430
|
|
336
|
-
assert_equal(
|
431
|
+
assert_equal(@@file_readable, smbfile.read)
|
337
432
|
|
433
|
+
assert_equal(false, smbfile.closed?)
|
338
434
|
smbfile.close
|
435
|
+
assert_equal(true, smbfile.closed?)
|
339
436
|
|
340
437
|
assert_raise(IOError) do
|
341
438
|
smbfile.close
|
342
439
|
end
|
440
|
+
assert_raise(IOError) do
|
441
|
+
smbfile.read(1)
|
442
|
+
end
|
443
|
+
assert_raise(IOError) do
|
444
|
+
smbfile.pos
|
445
|
+
end
|
446
|
+
assert_raise(IOError) do
|
447
|
+
smbfile.seek(0)
|
448
|
+
end
|
449
|
+
assert_raise(IOError) do
|
450
|
+
smbfile.eof?
|
451
|
+
end
|
343
452
|
end
|
344
453
|
end ## test_file_open_read_close
|
345
454
|
|
346
455
|
def test_file_read_sequential
|
347
456
|
smb = self.smb
|
348
457
|
|
349
|
-
file = File.open(
|
350
|
-
smbfile = smb.open(
|
458
|
+
file = File.open(@@share_dir + '/' + @@file_large)
|
459
|
+
smbfile = smb.open(@@share_public + '/' + @@file_large)
|
351
460
|
|
352
461
|
buffer_size = smbfile.read_buffer_size
|
353
462
|
[
|
@@ -374,11 +483,11 @@ class SMBTest < Test::Unit::TestCase
|
|
374
483
|
def test_file_read_eof
|
375
484
|
smb = self.smb
|
376
485
|
|
377
|
-
smbfile = smb.open(
|
486
|
+
smbfile = smb.open(@@share_public + '/' + @@file_readable)
|
378
487
|
|
379
|
-
|
488
|
+
assert_equal(false, smbfile.eof?)
|
380
489
|
smbfile.read
|
381
|
-
|
490
|
+
assert_equal(true, smbfile.eof?)
|
382
491
|
|
383
492
|
assert_equal("", smbfile.read)
|
384
493
|
assert_equal("", smbfile.read(0))
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: net-smb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-02-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake-compiler
|
@@ -36,11 +36,13 @@ extensions:
|
|
36
36
|
extra_rdoc_files: []
|
37
37
|
files:
|
38
38
|
- .gitignore
|
39
|
+
- CHANGES
|
39
40
|
- Gemfile
|
40
41
|
- Makefile
|
41
42
|
- README.md
|
42
43
|
- Rakefile
|
43
44
|
- Rakefile.local.example
|
45
|
+
- ext/net_smb/depend
|
44
46
|
- ext/net_smb/dlinklist.h
|
45
47
|
- ext/net_smb/extconf.rb
|
46
48
|
- ext/net_smb/rb_smb.h
|
@@ -48,6 +50,7 @@ files:
|
|
48
50
|
- ext/net_smb/smbdir.c
|
49
51
|
- ext/net_smb/smbdirentry.c
|
50
52
|
- ext/net_smb/smbfile.c
|
53
|
+
- ext/net_smb/smbstat.c
|
51
54
|
- lib/net/smb.rb
|
52
55
|
- lib/net/smb/version.rb
|
53
56
|
- net-smb.gemspec
|
@@ -65,7 +68,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
65
68
|
requirements:
|
66
69
|
- - ! '>='
|
67
70
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
71
|
+
version: 1.9.2
|
69
72
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
73
|
none: false
|
71
74
|
requirements:
|