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