1 |
// Spectre 2 |
2 |
// |
3 |
// Douglas Thrift |
4 |
// |
5 |
// $Id$ |
6 |
|
7 |
#include "Share.hpp" |
8 |
|
9 |
#include <stdio.h> |
10 |
|
11 |
ext::RedBlackMap<ext::String, ext::String> Share::passwords; |
12 |
api::ThreadMutex Share::passwordsLock; |
13 |
|
14 |
ext::String Share::getPassword() const |
15 |
{ |
16 |
// XXX: _unsynchronized |
17 |
_synchronized (passwordsLock) if (passwords.Contains(owner + "@" + host)) |
18 |
return passwords[owner + "@" + host]; |
19 |
|
20 |
_synchronized(passwordsLock) try |
21 |
{ |
22 |
api::FileReader in(Spectre2::prefix + "/etc/.spectre/" + owner + "@" + host); |
23 |
ext::String& password(passwords[owner + "@" + host]); |
24 |
|
25 |
ios::ReadLine(in, password); |
26 |
|
27 |
return password; |
28 |
} |
29 |
catch (const api::Error&) |
30 |
{ |
31 |
ext::String& password(passwords[owner + "@" + host]); |
32 |
|
33 |
password = ::getpass(("Password (" + owner + "@" + host + "):").NullTerminate()); |
34 |
|
35 |
return password; |
36 |
} |
37 |
|
38 |
throw api::UnexpectedErrorException(); |
39 |
} |
40 |
|
41 |
ext::String Share::getService() const |
42 |
{ |
43 |
#ifdef __FreeBSD__ |
44 |
return "//" + owner + "@" + operator ext::String(); |
45 |
#else |
46 |
return "//" + operator ext::String(); |
47 |
#endif |
48 |
} |
49 |
|
50 |
bool Share::mounted() const |
51 |
{ |
52 |
_L<ext::String> args(1, "-t"); |
53 |
|
54 |
args.InsertLast("smbfs"); |
55 |
|
56 |
_S<api::Process> mount(Spectre2::mount, args); |
57 |
ext::String line; |
58 |
#ifdef __FreeBSD__ |
59 |
Matcher matcher("^//.* on " + getMount() + " \\(smbfs\\)$"); |
60 |
#else |
61 |
Matcher matcher("^.* on " + getMount() + " type smbfs$"); |
62 |
#endif |
63 |
|
64 |
while (ios::ReadLine(*mount.GetReader(), line)) if (line == matcher) |
65 |
{ |
66 |
ios::Discard(*mount.GetReader()); |
67 |
|
68 |
return true; |
69 |
} |
70 |
|
71 |
return false; |
72 |
} |
73 |
|
74 |
bool Share::mountable() const |
75 |
{ |
76 |
try |
77 |
{ |
78 |
struct stat share; |
79 |
|
80 |
CheckError(::smbc_stat(getUri().NullTerminate(), &share)); |
81 |
|
82 |
return true; |
83 |
} |
84 |
catch (const Error&) |
85 |
{ |
86 |
return false; |
87 |
} |
88 |
} |
89 |
|
90 |
extern "C" |
91 |
{ |
92 |
void authenticate(const char* host, const char* name, char* work, int workSize, char* owner, int ownerSize, char* password, int passwordSize) |
93 |
{ |
94 |
const Share& share(*Daemon::shares.Find(Share(host, name))); |
95 |
const ext::Buffer& owner_(share.getOwner().GetData()); |
96 |
|
97 |
if (!owner_.IsEmpty()) |
98 |
{ |
99 |
_foreach (const ext::Buffer, atom, owner_) |
100 |
owner[_index] = *atom; |
101 |
|
102 |
owner[owner_.GetSize() < size_t(ownerSize) ? owner_.GetSize() : ownerSize - 1] = '\0'; |
103 |
} |
104 |
|
105 |
ext::Buffer password_(share.getPassword().GetData()); |
106 |
|
107 |
_foreach (ext::Buffer, atom, password_) |
108 |
password[_index] = *atom; |
109 |
|
110 |
password[password_.GetSize() < size_t(passwordSize) ? password_.GetSize() : passwordSize - 1] = '\0'; |
111 |
} |
112 |
} |