smb 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +5 -0
- data/Rakefile +48 -0
- data/ext/smb/extconf.rb +104 -0
- data/ext/smb/smb.c +1019 -0
- data/ext/smb/smb.cr +359 -0
- data/ext/smb/smb.rd +86 -0
- data/lib/smb.rb +2 -0
- data/lib/smb/version.rb +4 -0
- data/lib/smb/vfs.rb +215 -0
- metadata +90 -0
data/ext/smb/smb.cr
ADDED
@@ -0,0 +1,359 @@
|
|
1
|
+
%name smb
|
2
|
+
|
3
|
+
%include libsmbclient.h
|
4
|
+
%include ruby.h
|
5
|
+
%lib smbclient
|
6
|
+
|
7
|
+
%{
|
8
|
+
|
9
|
+
#define TO_STRING(v) ((v) ? rb_str_new2((v)) : Qnil)
|
10
|
+
|
11
|
+
static volatile VALUE auth_block = Qnil;
|
12
|
+
|
13
|
+
static void smbc_get_auth_data(const char *srv, const char *shr,
|
14
|
+
char *wg, int wglen,
|
15
|
+
char *un, int unlen,
|
16
|
+
char *pw, int pwlen)
|
17
|
+
{
|
18
|
+
volatile VALUE ret= Qnil;
|
19
|
+
|
20
|
+
|
21
|
+
ret = rb_funcall(auth_block, rb_intern("call"), 5, TO_STRING(srv), TO_STRING(shr),
|
22
|
+
TO_STRING(wg), TO_STRING(un), TO_STRING(pw));
|
23
|
+
|
24
|
+
if(TYPE(ret) == T_ARRAY && RARRAY_LEN(ret) == 3)
|
25
|
+
{
|
26
|
+
char * tmp;
|
27
|
+
volatile VALUE tmpv;
|
28
|
+
|
29
|
+
tmpv = RARRAY_PTR(ret)[0];
|
30
|
+
tmp = StringValuePtr(tmpv);
|
31
|
+
strncpy(wg, tmp, wglen);
|
32
|
+
|
33
|
+
tmpv = RARRAY_PTR(ret)[1];
|
34
|
+
tmp = StringValuePtr(tmpv);
|
35
|
+
strncpy(un, tmp, unlen);
|
36
|
+
|
37
|
+
tmpv = RARRAY_PTR(ret)[2];
|
38
|
+
tmp = StringValuePtr(tmpv);
|
39
|
+
strncpy(pw, tmp, pwlen);
|
40
|
+
|
41
|
+
CREDENTIALS_ADD(ret);
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
/*static VALUE rb_cStat;*/
|
46
|
+
|
47
|
+
typedef struct rb_smbprivate {
|
48
|
+
int handle;
|
49
|
+
char *url;
|
50
|
+
} rb_smbprivate;
|
51
|
+
|
52
|
+
static void smbprivate_free(rb_smbprivate *p)
|
53
|
+
{
|
54
|
+
if (p) {
|
55
|
+
if(p->url)
|
56
|
+
free(p->url);
|
57
|
+
free(p);
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
static VALUE stat_new(struct stat *st)
|
62
|
+
{
|
63
|
+
struct stat *nst = 0;
|
64
|
+
|
65
|
+
if (st) {
|
66
|
+
nst = ALLOC(struct stat);
|
67
|
+
*nst = *st;
|
68
|
+
}
|
69
|
+
return Data_Wrap_Struct(rb_cStat, NULL, free, nst);
|
70
|
+
}
|
71
|
+
|
72
|
+
%}
|
73
|
+
|
74
|
+
%pre_init{
|
75
|
+
/* rb_cStat = rb_eval_string("File::Stat");*/
|
76
|
+
%}
|
77
|
+
|
78
|
+
%map ruby - (char *) => (VALUE): rb_str_new2(#0)
|
79
|
+
%map string - (VALUE) => (char *): StringValuePtr(%%)
|
80
|
+
%map VALUE > off_t : NUM2OFFT(%%)
|
81
|
+
|
82
|
+
%option glib=no
|
83
|
+
|
84
|
+
gcpool Credentials
|
85
|
+
|
86
|
+
module SMB
|
87
|
+
enum Type (SMBC_WORKGROUP, SMBC_SERVER, SMBC_FILE_SHARE, SMBC_PRINTER_SHARE, SMBC_COMMS_SHARE, SMBC_IPC_SHARE, SMBC_DIR, SMBC_FILE, SMBC_LINK)
|
88
|
+
class CTX
|
89
|
+
pre_func SMBCCTX *ctx; Data_Get_Struct(self, SMBCCTX, ctx);
|
90
|
+
def self.default
|
91
|
+
return Data_Wrap_Struct(self, NULL, smbc_free_context, smbc_set_context(NULL));
|
92
|
+
end
|
93
|
+
def self.__alloc__
|
94
|
+
SMBCCTX *ctx = smbc_new_context();
|
95
|
+
volatile VALUE obj;
|
96
|
+
obj = Data_Wrap_Struct(self, NULL, smbc_free_context, ctx);
|
97
|
+
return obj;
|
98
|
+
end
|
99
|
+
def initialize()
|
100
|
+
smbc_init_context(ctx);
|
101
|
+
end
|
102
|
+
class SmbFile
|
103
|
+
|
104
|
+
end
|
105
|
+
def file_creat(char *url, int mode = 0666)
|
106
|
+
volatile VALUE rfile;
|
107
|
+
SMBCFILE *file = (smbc_getFunctionCreat(ctx))(ctx, url, mode);
|
108
|
+
rfile = Data_Wrap_Struct(cSmbFile, NULL, NULL, file);
|
109
|
+
return rfile;
|
110
|
+
end
|
111
|
+
def file_open(char *url, int flags = O_RDONLY, int mode = 0666)
|
112
|
+
volatile VALUE rfile;
|
113
|
+
SMBCFILE *file = ctx->open(ctx, url, flags, mode);
|
114
|
+
rfile = Data_Wrap_Struct(cSmbFile, NULL, NULL, file);
|
115
|
+
return rfile;
|
116
|
+
end
|
117
|
+
def long:file_write(T_DATA sfile, T_STRING data)
|
118
|
+
SMBCFILE *file; Data_Get_Struct(sfile, SMBCFILE, file);
|
119
|
+
StringValue(data);
|
120
|
+
return ctx->write(ctx, file, RSTRING_PTR(data), RSTRING_LEN(data));
|
121
|
+
end
|
122
|
+
def file_close(T_DATA sfile)
|
123
|
+
SMBCFILE *file; Data_Get_Struct(sfile, SMBCFILE, file);
|
124
|
+
ctx->close_fn(ctx, file);
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
def self.init(int debug = 0,&block)
|
130
|
+
auth_block = block;
|
131
|
+
|
132
|
+
rb_gc_register_address(&auth_block);
|
133
|
+
|
134
|
+
if (smbc_init(smbc_get_auth_data, debug) < 0)
|
135
|
+
{
|
136
|
+
rb_sys_fail("smbc_init failed");
|
137
|
+
}
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
struct DirEntry (type,comment,name);
|
142
|
+
|
143
|
+
class Dir
|
144
|
+
def self.new(char *url)
|
145
|
+
volatile VALUE val;
|
146
|
+
struct rb_smbprivate *dir;
|
147
|
+
int handle;
|
148
|
+
|
149
|
+
if((handle = smbc_opendir(url)) < 0)
|
150
|
+
{
|
151
|
+
rb_sys_fail("Unable to open dir URL");
|
152
|
+
}
|
153
|
+
|
154
|
+
val = Data_Make_Struct(self, struct rb_smbprivate, 0, smbprivate_free, dir);
|
155
|
+
dir->handle = handle;
|
156
|
+
|
157
|
+
rb_obj_call_init(val, 0, NULL);
|
158
|
+
return val;
|
159
|
+
end
|
160
|
+
def self.rmdir(char *url)
|
161
|
+
if (smbc_rmdir(url) < 0)
|
162
|
+
rb_sys_fail(url);
|
163
|
+
end
|
164
|
+
def self.mkdir(char *url, int mode)
|
165
|
+
if (smbc_mkdir(url, mode) < 0)
|
166
|
+
rb_sys_fail(url);
|
167
|
+
end
|
168
|
+
|
169
|
+
pre_func rb_smbprivate *dir; Data_Get_Struct(self, rb_smbprivate, dir);
|
170
|
+
|
171
|
+
def initialize()
|
172
|
+
end
|
173
|
+
def read_entry
|
174
|
+
struct smbc_dirent* de;
|
175
|
+
de = smbc_readdir(dir->handle);
|
176
|
+
if(de)
|
177
|
+
{
|
178
|
+
return rb_struct_new(structDirEntry,
|
179
|
+
<{int>VALUE:de->smbc_type}>,
|
180
|
+
<{char*>VALUE:de->comment}>,
|
181
|
+
<{char*>VALUE:de->name}>);
|
182
|
+
}
|
183
|
+
end
|
184
|
+
def char*:read
|
185
|
+
struct smbc_dirent* de;
|
186
|
+
de = smbc_readdir(dir->handle);
|
187
|
+
if(de)
|
188
|
+
return de->name;
|
189
|
+
end
|
190
|
+
def int:tell()
|
191
|
+
return smbc_telldir(dir->handle);
|
192
|
+
end
|
193
|
+
def char *:url
|
194
|
+
return dir->url;
|
195
|
+
end
|
196
|
+
def close()
|
197
|
+
smbc_closedir(dir->handle);
|
198
|
+
dir->handle = 0;
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
class File
|
203
|
+
def self.new(char *url, int flags, int mode)
|
204
|
+
volatile VALUE val;
|
205
|
+
struct rb_smbprivate *file;
|
206
|
+
int handle = 0;
|
207
|
+
|
208
|
+
if ((handle = smbc_open(url, flags, mode)) < 0)
|
209
|
+
{
|
210
|
+
rb_sys_fail(url);
|
211
|
+
}
|
212
|
+
|
213
|
+
|
214
|
+
val = Data_Make_Struct(self, struct rb_smbprivate, 0, smbprivate_free, file);
|
215
|
+
file->handle = handle;
|
216
|
+
file->url = strdup(url);
|
217
|
+
|
218
|
+
rb_obj_call_init(val, 0, NULL);
|
219
|
+
return val;
|
220
|
+
end
|
221
|
+
def self.create(char *url, int mode)
|
222
|
+
volatile VALUE val;
|
223
|
+
struct rb_smbprivate *file;
|
224
|
+
int handle = 0;
|
225
|
+
|
226
|
+
if ((handle = smbc_creat(url, mode)) < 0)
|
227
|
+
{
|
228
|
+
rb_sys_fail(url);
|
229
|
+
}
|
230
|
+
|
231
|
+
|
232
|
+
val = Data_Make_Struct(self, struct rb_smbprivate, 0, smbprivate_free, file);
|
233
|
+
file->handle = handle;
|
234
|
+
file->url = strdup(url);
|
235
|
+
|
236
|
+
rb_obj_call_init(val, 0, NULL);
|
237
|
+
return val;
|
238
|
+
end
|
239
|
+
def self.unlink(char *url)
|
240
|
+
if (smbc_unlink(url) < 0)
|
241
|
+
rb_sys_fail(url);
|
242
|
+
end
|
243
|
+
def self.rename(char *ourl, char *nurl)
|
244
|
+
if (smbc_rename(ourl, nurl) < 0)
|
245
|
+
rb_sys_fail(ourl);
|
246
|
+
end
|
247
|
+
def self.stat(char *url)
|
248
|
+
struct stat s;
|
249
|
+
if (smbc_stat(url, &s) < 0)
|
250
|
+
rb_sys_fail(url);
|
251
|
+
return stat_new(&s);
|
252
|
+
end
|
253
|
+
|
254
|
+
pre_func rb_smbprivate *file; Data_Get_Struct(self, rb_smbprivate, file);
|
255
|
+
|
256
|
+
def initialize()
|
257
|
+
end
|
258
|
+
def stat()
|
259
|
+
struct stat s;
|
260
|
+
if (smbc_fstat(file->handle, &s) < 0)
|
261
|
+
rb_sys_fail(file->url);
|
262
|
+
return stat_new(&s);
|
263
|
+
end
|
264
|
+
def char *:url
|
265
|
+
return file->url;
|
266
|
+
end
|
267
|
+
def seek(off_t offset, int whence)
|
268
|
+
return INT2NUM(smbc_lseek(file->handle, offset, whence));
|
269
|
+
end
|
270
|
+
def read(int bytes_to_read=-1)
|
271
|
+
size_t read;
|
272
|
+
struct stat s;
|
273
|
+
char buf[4096];
|
274
|
+
volatile VALUE str = Qnil;
|
275
|
+
int next_read = 0;
|
276
|
+
|
277
|
+
if(bytes_to_read == -1)
|
278
|
+
{
|
279
|
+
if (smbc_fstat(file->handle, &s) < 0)
|
280
|
+
rb_sys_fail(file->url);
|
281
|
+
|
282
|
+
bytes_to_read = s.st_size;
|
283
|
+
}
|
284
|
+
|
285
|
+
if(bytes_to_read > sizeof(buf))
|
286
|
+
next_read = sizeof(buf);
|
287
|
+
else
|
288
|
+
next_read = bytes_to_read;
|
289
|
+
|
290
|
+
while((read = smbc_read(file->handle, buf, next_read))!=0)
|
291
|
+
{
|
292
|
+
if(str == Qnil)
|
293
|
+
str = rb_str_new("",0);
|
294
|
+
rb_str_cat(str, buf, read);
|
295
|
+
bytes_to_read -= read;
|
296
|
+
if(bytes_to_read == 0)
|
297
|
+
break;
|
298
|
+
|
299
|
+
if(bytes_to_read > sizeof(buf))
|
300
|
+
next_read = sizeof(buf);
|
301
|
+
else
|
302
|
+
next_read = bytes_to_read;
|
303
|
+
}
|
304
|
+
|
305
|
+
return str;
|
306
|
+
end
|
307
|
+
def long:write(T_STRING buf)
|
308
|
+
int i;
|
309
|
+
StringValue(buf);
|
310
|
+
i = smbc_write(file->handle, RSTRING_PTR(buf), RSTRING_LEN(buf));
|
311
|
+
if (i < 0)
|
312
|
+
rb_sys_fail("write");
|
313
|
+
return i;
|
314
|
+
end
|
315
|
+
def close()
|
316
|
+
smbc_close(file->handle);
|
317
|
+
file->handle = 0;
|
318
|
+
end
|
319
|
+
|
320
|
+
def self.read(char *url)
|
321
|
+
size_t read;
|
322
|
+
struct stat s;
|
323
|
+
char buf[4096];
|
324
|
+
volatile VALUE str;
|
325
|
+
int next_read = 0, handle, bytes_to_read;
|
326
|
+
|
327
|
+
if ((handle = smbc_open(url, O_RDONLY, 0)) < 0)
|
328
|
+
rb_sys_fail(url);
|
329
|
+
|
330
|
+
if (smbc_fstat(handle, &s) < 0)
|
331
|
+
rb_sys_fail(url);
|
332
|
+
bytes_to_read = s.st_size;
|
333
|
+
|
334
|
+
if(bytes_to_read > sizeof(buf))
|
335
|
+
next_read = sizeof(buf);
|
336
|
+
else
|
337
|
+
next_read = bytes_to_read;
|
338
|
+
|
339
|
+
str = rb_str_new("",0);
|
340
|
+
|
341
|
+
while((read = smbc_read(handle, buf, next_read))!=0)
|
342
|
+
{
|
343
|
+
rb_str_cat(str, buf, read);
|
344
|
+
bytes_to_read -= read;
|
345
|
+
if(bytes_to_read == 0)
|
346
|
+
break;
|
347
|
+
|
348
|
+
if(bytes_to_read > sizeof(buf))
|
349
|
+
next_read = sizeof(buf);
|
350
|
+
else
|
351
|
+
next_read = bytes_to_read;
|
352
|
+
}
|
353
|
+
|
354
|
+
smbc_close(handle);
|
355
|
+
|
356
|
+
return str;
|
357
|
+
end
|
358
|
+
end
|
359
|
+
end
|
data/ext/smb/smb.rd
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
= module SMB
|
2
|
+
--- SMB.init(Integer debug, block)
|
3
|
+
|
4
|
+
|
5
|
+
== enum SMB::Type
|
6
|
+
== class SMB::CTX
|
7
|
+
--- SMB::CTX.default()
|
8
|
+
|
9
|
+
|
10
|
+
--- SMB::CTX__alloc__()
|
11
|
+
|
12
|
+
|
13
|
+
--- SMB::CTX.new
|
14
|
+
|
15
|
+
--- SMB::CTX#file_creat(String url, Integer mode)
|
16
|
+
|
17
|
+
|
18
|
+
--- SMB::CTX#file_open(String url, Integer flags, Integer mode)
|
19
|
+
|
20
|
+
|
21
|
+
--- SMB::CTX#file_write(Data sfile, String data)
|
22
|
+
|
23
|
+
|
24
|
+
--- SMB::CTX#file_close(Data sfile)
|
25
|
+
|
26
|
+
|
27
|
+
=== class SMB::CTX::SmbFile
|
28
|
+
== enum SMB::DirEntry
|
29
|
+
== class SMB::Dir
|
30
|
+
--- SMB::Dir.new(String url)
|
31
|
+
|
32
|
+
|
33
|
+
--- SMB::Dir.rmdir(String url)
|
34
|
+
|
35
|
+
|
36
|
+
--- SMB::Dir.mkdir(String url, Integer mode)
|
37
|
+
|
38
|
+
|
39
|
+
--- SMB::Dir.new
|
40
|
+
|
41
|
+
--- SMB::Dir#read_entry
|
42
|
+
|
43
|
+
--- SMB::Dir#read
|
44
|
+
|
45
|
+
--- SMB::Dir#tell
|
46
|
+
|
47
|
+
--- SMB::Dir#url
|
48
|
+
|
49
|
+
--- SMB::Dir#close
|
50
|
+
|
51
|
+
== class SMB::File
|
52
|
+
--- SMB::File.new(String url, Integer flags, Integer mode)
|
53
|
+
|
54
|
+
|
55
|
+
--- SMB::File.create(String url, Integer mode)
|
56
|
+
|
57
|
+
|
58
|
+
--- SMB::File.unlink(String url)
|
59
|
+
|
60
|
+
|
61
|
+
--- SMB::File.rename(String ourl, String nurl)
|
62
|
+
|
63
|
+
|
64
|
+
--- SMB::File.stat(String url)
|
65
|
+
|
66
|
+
|
67
|
+
--- SMB::File.new
|
68
|
+
|
69
|
+
--- SMB::File#stat
|
70
|
+
|
71
|
+
--- SMB::File#url
|
72
|
+
|
73
|
+
--- SMB::File#seek(off_t offset, Integer whence)
|
74
|
+
|
75
|
+
|
76
|
+
--- SMB::File#read(Integer bytes_to_read)
|
77
|
+
|
78
|
+
|
79
|
+
--- SMB::File#write(String buf)
|
80
|
+
|
81
|
+
|
82
|
+
--- SMB::File#close
|
83
|
+
|
84
|
+
--- SMB::File.read(String url)
|
85
|
+
|
86
|
+
|
data/lib/smb.rb
ADDED
data/lib/smb/version.rb
ADDED