Skip to content

Commit 0acf5f1

Browse files
committed
Add directory support to smbc
1 parent 7bf7625 commit 0acf5f1

File tree

2 files changed

+103
-5
lines changed

2 files changed

+103
-5
lines changed

src/lib.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,6 @@
2424
//!
2525
//! Files are represented by [`SmbFile`](struct.SmbFile.html).
2626
//!
27-
//! Basic example:
28-
//! ```rust
29-
//! fn load
30-
//! # fn main() {}
31-
//! ```
3227
3328
#[macro_use]
3429
extern crate log;

src/smbc.rs

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@
2020
2121
// imports {{{1
2222
use std::default::Default;
23+
use std::ffi::CStr;
2324
use std::io;
2425
use std::mem;
2526
use std::panic;
27+
use std::path::PathBuf;
2628
use std::ptr;
2729

2830
use std::borrow::Cow;
@@ -126,6 +128,81 @@ pub struct SmbFile<'a: 'b, 'b> {
126128
}
127129
// 1}}}
128130

131+
pub struct SmbDirectory<'a: 'b, 'b> {
132+
smbc: &'b SmbClient<'a>,
133+
fd: *mut SMBCFILE,
134+
}
135+
136+
#[derive(Debug)]
137+
pub struct DirEntry {
138+
pub path: PathBuf,
139+
pub name: String,
140+
pub comment: String,
141+
pub file_type: SmbcType,
142+
}
143+
144+
#[derive(Debug)]
145+
pub enum SmbcType {
146+
Workgroup,
147+
Server,
148+
FileShare,
149+
PrinterShare,
150+
CommsShare,
151+
IpcShare,
152+
Dir,
153+
File,
154+
Link,
155+
Unknown,
156+
}
157+
158+
impl From<u32> for SmbcType {
159+
fn from(i: u32) -> Self {
160+
match i {
161+
1 => SmbcType::Workgroup,
162+
2 => SmbcType::Server,
163+
3 => SmbcType::FileShare,
164+
4 => SmbcType::PrinterShare,
165+
5 => SmbcType::CommsShare,
166+
6 => SmbcType::IpcShare,
167+
7 => SmbcType::Dir,
168+
8 => SmbcType::File,
169+
9 => SmbcType::Link,
170+
_ => SmbcType::Unknown,
171+
}
172+
}
173+
}
174+
175+
impl<'a, 'b> Iterator for SmbDirectory<'a, 'b> {
176+
type Item = DirEntry;
177+
fn next(&mut self) -> Option<DirEntry> {
178+
unsafe {
179+
let next_entry = smbc_readdir(self.fd as u32);
180+
/*
181+
@return A pointer to a smbc_dirent structure, or NULL if an
182+
error occurs or end-of-directory is reached:
183+
- EBADF Invalid directory handle
184+
- EINVAL smbc_init() failed or has not been called
185+
186+
*/
187+
// TODO: How do I check for an error occuring here?
188+
if next_entry.is_null(){
189+
// End of stream reached or error
190+
return None;
191+
}
192+
let file_name = CStr::from_ptr((*next_entry).name.as_ptr());
193+
let comment = CStr::from_ptr((*next_entry).comment);
194+
let file_type = SmbcType::from((*next_entry).smbc_type);
195+
return Some(DirEntry {
196+
path: PathBuf::from(file_name.to_string_lossy().into_owned()),
197+
name: file_name.to_string_lossy().into_owned(),
198+
comment: comment.to_string_lossy().into_owned(),
199+
file_type: file_type,
200+
});
201+
}
202+
}
203+
}
204+
205+
129206
/// Default (dummy) credential `WORKGROUP\guest` with empty password
130207
const DEF_CRED: (Cow<'static, str>, Cow<'static, str>, Cow<'static, str>) = (Cow::Borrowed("WORKGROUP"), Cow::Borrowed("guest"), Cow::Borrowed(""));
131208

@@ -233,6 +310,23 @@ impl<'a> SmbClient<'a> {
233310
self.open_ro(path)
234311
}
235312

313+
/// Open a directory used to obtain directory entries.
314+
pub fn opendir<'b, P: AsRef<str>>(&'b self, path: P) -> Result<SmbDirectory<'a, 'b>> {
315+
let path = try!(cstring(path));
316+
unsafe {
317+
let open_fn = try_ufn!(smbc_getFunctionOpendir <- self);
318+
let fd = try!(result_from_ptr_mut(open_fn(self.ctx, path.as_ptr())));
319+
320+
if (fd as i64) < 0 {
321+
trace!(target: "smbc", "neg fd");
322+
}
323+
Ok(SmbDirectory {
324+
smbc: &self,
325+
fd: fd,
326+
})
327+
}
328+
}
329+
236330
/// Open write-only [`SmbFile`](struct.SmbFile.html) defined by SMB `path`.
237331
///
238332
/// If file doesn't exists it will be created.
@@ -482,4 +576,13 @@ impl<'a, 'b> Drop for SmbFile<'a, 'b> {
482576
} // }}}
483577
// 1}}}
484578

579+
impl<'a, 'b> Drop for SmbDirectory<'a, 'b> {
580+
// {{{2
581+
fn drop(&mut self) {
582+
trace!(target: "smbc", "closing directory");
583+
unsafe {
584+
smbc_getFunctionClosedir(self.smbc.ctx).map(|f| f(self.smbc.ctx, self.fd));
585+
}
586+
}
587+
}
485588
// vim: fen:fdm=marker:fdl=1:

0 commit comments

Comments
 (0)