// Spectre 2 // // Douglas Thrift // // $Id$ #include "Share.hpp" #include ext::RedBlackMap Share::passwords; api::ThreadMutex Share::passwordsLock; ext::String Share::getPassword() const { // XXX: _unsynchronized _synchronized (passwordsLock) if (passwords.Contains(owner + "@" + host)) return passwords[owner + "@" + host]; _synchronized(passwordsLock) try { api::FileReader in(Spectre2::prefix + "/etc/.spectre/" + owner + "@" + host); ext::String& password(passwords[owner + "@" + host]); ios::ReadLine(in, password); return password; } catch (const api::Error&) { ext::String& password(passwords[owner + "@" + host]); password = ::getpass(("Password (" + owner + "@" + host + "):").NullTerminate()); return password; } throw api::UnexpectedErrorException(); } 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; // XXX: _unsynchronized // _synchronized (Daemon::smbcLock) CheckError(::smbc_stat(getUri().NullTerminate(), &share)); return true; } catch (const Error&) { return false; } } 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(*Daemon::shares.Find(Share(host, name))); const ext::Buffer& owner_(share.getOwner().GetData()); if (!owner_.IsEmpty()) { _foreach (const ext::Buffer, atom, owner_) owner[_index] = *atom; owner[owner_.GetSize() < size_t(ownerSize) ? owner_.GetSize() : ownerSize - 1] = '\0'; } ext::Buffer password_(share.getPassword().GetData()); _foreach (ext::Buffer, atom, password_) password[_index] = *atom; password[password_.GetSize() < size_t(passwordSize) ? password_.GetSize() : passwordSize - 1] = '\0'; } }