// Spectre Samba Mounter // // Douglas Thrift // // Mounter.cpp #ifdef _FreeBSD_ #include #endif #include "Mounter.h" void Mounter::mount() { samba(); if (debug) { cerr << "mounted = {\n"; for (set::iterator itor = mounted.begin(); itor != mounted.end(); itor++) { cerr << " " << *itor << "\n"; } cerr << "}\n"; } if (debug) cerr << "folders = {\n"; for (map::iterator itor = folders.begin(); itor != folders.end(); itor++) { if (debug) cerr << " " << itor->first << " = {\n" << " local = " << itor->second.local << "\n" << " remote = " << itor->second.remote << "\n" << " }\n"; mount(itor->first, itor->second.local, itor->second.remote); } if (debug) cerr << "}\n"; } void Mounter::samba() { string path = config.root + "/" + host; DIR* dir = opendir(path.c_str()); dirent* file; while ((file = readdir(dir)) != NULL) { struct stat dir; string folder = path + "/" + file->d_name; stat(folder.c_str(), &dir); if (S_ISDIR(dir.st_mode)) { string folder = file->d_name; if (folder == "." || folder == "..") continue; string share = folder.find('.') == 0 ? folder.erase(0, 1) + "$" : folder; if (folders.find(share) == folders.end()) { folders.insert(pair(share, regular)); } } } closedir(dir); vector args; args.push_back("spectre"); args.push_back("-t"); args.push_back("smbfs"); ipstream mount(config.mount, args); if (debug) cerr << "mount = {\n"; samba(mount); if (debug) cerr << "}\n"; mount.close(); } void Mounter::samba(ipstream& pin) { while (pin.good()) { string line; getline(pin, line); if (debug) cerr << line << "\n"; if (line == "") continue; unsigned begin = line.find(" on ") + 4; #if defined _Linux_ unsigned end = line.rfind(" type smbfs"); #elif defined _FreeBSD_ unsigned end = line.rfind(" (smbfs)"); #endif string path = line.substr(begin, end - begin); if (mounted.find(path) == mounted.end()) { mounted.insert(path); } } } void Mounter::mount(const string& folder, const string& user, const string& owner) { string path = config.root + "/" + host + "/" + folder; if (mounted.find(path) != mounted.end()) return; ostringstream options; struct passwd* item = getpwnam(user.c_str()); if (item == NULL) { cerr << program << ": " << user << ": Unknown user\n"; return; } #if defined _Linux_ char credentials[17]; sprintf(credentials, "%s", "/tmp/spectre.XXXX"); mkstemp(credentials); ofstream fout(credentials); fout << "username = " << owner << "\n" << "password = " << password(owner) << "\n"; fout.close(); options << "credentials=" << credentials << "," << "uid=" << item->pw_uid << "," << "gid=" << item->pw_gid; string smb = "//" + host + "/" + folder; #elif defined _FreeBSD_ char* credentials = "~/.nsmbrc"; int dot = open(credentials, O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); close(dot); ofstream fout(credentials); fout << "[default]\n" << "password=" << password(owner) << "\n"; fout.close(); options << "-N," << "-u=" << item->pw_uid << "," << "-g=" << item->pw_gid; string smb = "//" + owner + "@" + host + "/" + folder; #endif vector args; args.push_back("spectre"); #ifdef _FreeBSD_ args.push_back("-o"); args.push_back(options.str()); #endif args.push_back("-t"); args.push_back("smbfs"); #ifdef _Linux_ args.push_back("-o"); args.push_back(options.str()); #endif args.push_back(smb); args.push_back(path); ipstream mount(config.mount, args, pstreambuf::pstderr); while (mount.good()) { string line; getline(mount, line); if (line != "") cerr << line << "\n"; } mount.close(); unlink(credentials); }