Skip to content

Commit a852ddf

Browse files
committed
Use separate smb shares for each partition (fixes #42)
1 parent 3c4381f commit a852ddf

File tree

6 files changed

+123
-31
lines changed

6 files changed

+123
-31
lines changed

pISO/src/action.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,8 @@ pub enum Action {
3838
FlipDisplay,
3939

4040
OpenVersion,
41-
CloseVersion
41+
CloseVersion,
42+
43+
SmbSharePartition(String),
44+
SmbRemoveShare(String),
4245
}

pISO/src/options.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub struct Options {
1919
removable: buttons::vdrivelist::DriveList,
2020
delete: buttons::vdrivelist::DriveList,
2121
snapshot: buttons::vdrivelist::DriveList,
22-
version: version::VersionMenu
22+
version: version::VersionMenu,
2323
}
2424

2525
impl Options {
@@ -79,7 +79,7 @@ impl Options {
7979
removable: removable,
8080
delete: delete,
8181
snapshot: snapshot,
82-
version: version
82+
version: version,
8383
})
8484
}
8585
}
@@ -120,7 +120,7 @@ impl Widget for Options {
120120
&mut self.removable as &mut Widget,
121121
&mut self.snapshot as &mut Widget,
122122
&mut self.delete as &mut Widget,
123-
&mut self.version as &mut Widget
123+
&mut self.version as &mut Widget,
124124
]
125125
} else {
126126
vec![]
@@ -134,7 +134,7 @@ impl Widget for Options {
134134
&self.removable as &Widget,
135135
&self.snapshot as &Widget,
136136
&self.delete as &Widget,
137-
&self.version as &Widget
137+
&self.version as &Widget,
138138
]
139139
} else {
140140
vec![]

pISO/src/piso.rs

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -107,18 +107,45 @@ impl PIso {
107107
Ok(drives)
108108
}
109109

110-
fn add_drive(
111-
&mut self,
112-
disp: &mut DisplayManager,
110+
fn add_drive<'a, 'b>(
111+
&'a mut self,
112+
disp: &'b mut DisplayManager,
113113
volume: lvm::LogicalVolume,
114-
) -> Result<&vdrive::VirtualDrive> {
115-
let vdrive = vdrive::VirtualDrive::new(disp, self.usb.clone(), volume, &self.config)?;
114+
) -> Result<&'a mut vdrive::VirtualDrive> {
115+
let mut vdrive = vdrive::VirtualDrive::new(disp, self.usb.clone(), volume, &self.config)?;
116+
vdrive.mount_internal(disp)?;
116117
self.drives.push(vdrive);
117118

118119
Ok(self.drives
119-
.last()
120+
.last_mut()
120121
.expect("vdrive was somehow empty after push"))
121122
}
123+
124+
fn share_drive(drive: &mut vdrive::VirtualDrive, remove: bool) -> Result<Vec<action::Action>> {
125+
match drive.state {
126+
vdrive::MountState::Unmounted | vdrive::MountState::External(_) => {
127+
if remove {
128+
Ok(vec![])
129+
} else {
130+
Err("Cannot share drive when not mounted internal".into())
131+
}
132+
}
133+
vdrive::MountState::Internal(ref info) => Ok(info.part_mount_paths
134+
.iter()
135+
.map(|path| {
136+
let name = path.file_name()
137+
.expect("Partition has no name")
138+
.to_string_lossy()
139+
.into_owned();
140+
if remove {
141+
action::Action::SmbRemoveShare(name)
142+
} else {
143+
action::Action::SmbSharePartition(name)
144+
}
145+
})
146+
.collect()),
147+
}
148+
}
122149
}
123150

124151
impl render::Render for PIso {
@@ -145,23 +172,27 @@ impl input::Input for PIso {
145172
Ok((true, vec![]))
146173
}
147174
action::Action::CreateDrive(ref volume) => {
148-
self.add_drive(disp, volume.clone())?;
149-
Ok((true, vec![]))
175+
let drive = self.add_drive(disp, volume.clone())?;
176+
let actions = PIso::share_drive(drive, false)?;
177+
Ok((true, actions))
150178
}
151179
action::Action::SnapshotDrive(ref name) => {
152180
let report = self.vg.snapshot_volume(name)?;
153-
self.add_drive(disp, report)?;
154-
Ok((true, vec![]))
181+
let drive = self.add_drive(disp, report)?;
182+
let actions = PIso::share_drive(drive, false)?;
183+
Ok((true, actions))
155184
}
156185
action::Action::DeleteDrive(ref name) => {
186+
let mut actions = vec![];
157187
if let Some(ref mut drive) =
158188
self.drives.iter_mut().find(|drive| drive.name() == name)
159189
{
190+
actions = PIso::share_drive(drive, true)?;
160191
drive.unmount()?;
161192
}
162193
self.drives.retain(|drive| drive.name() != name);
163194
self.vg.delete_volume(&name)?;
164-
Ok((true, vec![]))
195+
Ok((true, actions))
165196
}
166197
_ => Ok((false, vec![])),
167198
}

pISO/src/vdrive.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,10 @@ impl VirtualDrive {
152152
).into())
153153
}
154154

155-
pub fn mount_internal(&mut self, disp: &mut DisplayManager) -> Result<()> {
155+
pub fn mount_internal<'a, 'b>(
156+
&'a mut self,
157+
disp: &'b mut DisplayManager,
158+
) -> Result<&'a MountInfo> {
156159
match self.state {
157160
MountState::Unmounted => {
158161
let volume_path = &self.volume.path.to_string_lossy();
@@ -222,9 +225,12 @@ impl VirtualDrive {
222225
isos: isos,
223226
loopback_path: loopback_path.to_path_buf(),
224227
});
225-
Ok(())
228+
match &self.state {
229+
&MountState::Internal(ref info) => Ok(info),
230+
_ => unreachable!(),
231+
}
226232
}
227-
MountState::Internal(_) => Ok(()),
233+
MountState::Internal(ref state) => Ok(state),
228234
MountState::External(_) => {
229235
Err("Attempt to mount_internal while mounted external".into())
230236
}
@@ -262,7 +268,8 @@ impl VirtualDrive {
262268
}
263269
MountState::External(_) => {
264270
self.unmount_external()?;
265-
self.mount_internal(disp)
271+
self.mount_internal(disp)?;
272+
Ok(())
266273
}
267274
}
268275
}

pISO/src/version.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use action;
22
use bitmap;
33
use controller;
4+
use display;
45
use displaymanager::{DisplayManager, Position, Widget, Window, WindowId};
56
use error;
67
use font;
@@ -56,14 +57,14 @@ enum VersionState {
5657

5758
pub struct VersionMenu {
5859
pub window: WindowId,
59-
state: VersionState
60+
state: VersionState,
6061
}
6162

6263
impl VersionMenu {
6364
pub fn new(disp: &mut DisplayManager) -> error::Result<VersionMenu> {
6465
Ok(VersionMenu {
6566
window: disp.add_child(Position::Normal)?,
66-
state: VersionState::Unselected
67+
state: VersionState::Unselected,
6768
})
6869
}
6970
}
@@ -97,8 +98,7 @@ impl input::Input for VersionMenu {
9798
) -> error::Result<(bool, Vec<action::Action>)> {
9899
match *action {
99100
action::Action::OpenVersion => {
100-
let menu =
101-
OpenVersionMenu::new(disp)?;
101+
let menu = OpenVersionMenu::new(disp)?;
102102
disp.shift_focus(&menu);
103103
self.state = VersionState::Selected(menu);
104104
Ok((true, vec![]))
@@ -135,10 +135,8 @@ impl Widget for VersionMenu {
135135
}
136136
}
137137

138-
139-
140138
struct OpenVersionMenu {
141-
pub window: WindowId
139+
pub window: WindowId,
142140
}
143141

144142
impl OpenVersionMenu {

pISO/src/wifi.rs

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ const HOSTAPD_TMP_CONF: &'static str = "/tmp/hostapd.conf";
2222
const WPA_SUPPLICANT_CONF: &'static str = "/etc/wpa_supplicant.conf";
2323
const WPA_SUPPLICANT_TMP_CONF: &'static str = "/tmp/wpa_supplicant.conf";
2424
const SMB_CONF: &'static str = "/etc/samba/smb.conf";
25-
const SMB_TMP_CONF: &'static str = "/tmp/smb.conf";
2625
const PURE_FTPD_CONF: &'static str = "/etc/pure-ftpd.conf";
2726

2827
#[derive(PartialEq)]
@@ -46,6 +45,10 @@ impl WifiManager {
4645
}))
4746
}
4847

48+
fn is_enabled(&self) -> bool {
49+
self.state != WifiState::Uninitialized
50+
}
51+
4952
fn enable_wifi(&mut self) -> error::Result<()> {
5053
if self.state != WifiState::Uninitialized {
5154
return Ok(());
@@ -87,13 +90,55 @@ impl WifiManager {
8790
&[&self.config.user.name, &self.config.user.password],
8891
)?;
8992

90-
fs::copy(SMB_CONF, SMB_TMP_CONF)?;
91-
utils::run_check_output("smbd", &["-D", "-s", SMB_TMP_CONF])?;
92-
utils::run_check_output("nmbd", &["-D", "-s", SMB_TMP_CONF])?;
93+
// Setup usershare folder
94+
fs::create_dir_all("/var/lib/samba/usershares")?;
95+
utils::run_check_output("chmod", &["1770", "/var/lib/samba/usershares"])?;
96+
97+
utils::run_check_output("smbd", &["-D", "-s", SMB_CONF])?;
98+
utils::run_check_output("nmbd", &["-D", "-s", SMB_CONF])?;
9399

94100
utils::run_check_output("pure-ftpd", &[PURE_FTPD_CONF])?;
95101

96102
self.state = WifiState::Inactive;
103+
104+
for entry in fs::read_dir("/mnt")? {
105+
let entry = entry?;
106+
let path = entry.path();
107+
let name = path.file_name()
108+
.expect("Partition has no name")
109+
.to_string_lossy()
110+
.into_owned();
111+
self.share_mounted_partition(&name)?;
112+
}
113+
114+
Ok(())
115+
}
116+
117+
fn share_mounted_partition(&mut self, name: &str) -> error::Result<()> {
118+
if !self.is_enabled() {
119+
return Ok(());
120+
}
121+
122+
let path = "/user-mnt/".to_owned() + name;
123+
utils::run_check_output(
124+
"net",
125+
&[
126+
"usershare",
127+
"add",
128+
name,
129+
&path,
130+
"",
131+
&format!("piso\\{}:F", &self.config.user.name),
132+
],
133+
)?;
134+
Ok(())
135+
}
136+
137+
fn remove_shared_partition(&mut self, name: &str) -> error::Result<()> {
138+
if !self.is_enabled() {
139+
return Ok(());
140+
}
141+
utils::run_check_output("net", &["usershare", "delete", &name])?;
97142
Ok(())
98143
}
99144

@@ -262,6 +307,14 @@ impl input::Input for WifiMenu {
262307
disp.shift_focus(self);
263308
Ok((true, vec![]))
264309
}
310+
action::Action::SmbSharePartition(ref name) => {
311+
self.manager.lock()?.share_mounted_partition(name)?;
312+
Ok((true, vec![]))
313+
}
314+
action::Action::SmbRemoveShare(ref name) => {
315+
self.manager.lock()?.remove_shared_partition(name)?;
316+
Ok((true, vec![]))
317+
}
265318
_ => Ok((false, vec![])),
266319
}
267320
}

0 commit comments

Comments
 (0)