// Spectre 2 // // Douglas Thrift // // $Id$ #include "Share.hpp" #include #include extern "C" { void authenticate(const char* server, const char* share, char* work, int workSize, char* user, int userSize, char* password, int passwordSize); } 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) { if (!initialized) { CheckError(::smbc_init(authenticate, Spectre2::debug ? 2 : 0)); initialized = true; } } ext::String Share::getPassword() const { _synchronized (passwordsLock) if (passwords.Contains(owner + "@" + host)) return passwords[owner + "@" + host]; try { api::FileReader in(Spectre2::prefix + "/etc/." + owner + "@" + host); ext::String password(ios::ReadLine(in)); _synchronized (passwordsLock) passwords[owner + "@" + host] = password; return password; } catch (const api::Error&) { ext::String password(::getpass(("Password (" + owner + "@" + host + "):").NullTerminate())); _synchronized (passwordsLock) passwords[owner + "@" + host] = password; return password; } } ext::String Share::getService() const { #ifdef __FreeBSD__ return "//" + owner + "@" + operator ext::String(); #else return "//" + operator ext::String(); #endif } bool Share::mounted() const { _L args(1, "-t"); args.InsertLast("smbfs"); _S mount(Spectre2::mount, args); ext::String line; #ifdef __FreeBSD__ Matcher matcher("^//.* on " + getMount() + " \\(smbfs\\)$"); #else Matcher matcher("^.* on " + getMount() + " type smbfs$"); #endif while (ios::ReadLine(*mount.GetReader(), line)) if (line == matcher) { ios::Discard(*mount.GetReader()); return true; } return false; } bool Share::mountable() const { try { struct stat share; CheckError(::smbc_stat(getUri().NullTerminate(), &share)); return true; } catch (const Error&) { return false; } } bool Share::initialized(false); ext::RedBlackMap Share::passwords; api::ThreadMutex Share::passwordsLock; extern "C" { void authenticate(const char* host, const char* name, char* work, int workSize, char* owner, int ownerSize, char* password, int passwordSize) { const Share& share(*Spectre2::shares.Find(Share(host, name))); if (!share.getOwner().IsEmpty()) ::snprintf(owner, ownerSize, "%s", share.getOwner().NullTerminate()); ::snprintf(password, passwordSize, "%s", share.getPassword().NullTerminate()); } }