static void free_strings(string_set &s) { for (string_set::iterator i=s.begin(); i!=s.end(); i++) { free((void*)*i); } s.clear(); }
string_set operator+(const string_set& a_, const string_set& b_) { string_set r(a_); for (string_set::iterator i = b_.begin(), e = b_.end(); i != e; ++i) { r._data.insert(*i); } return r; }
static const char* unique_string(const char *name) { int unique = 2; string_set::iterator i = all_strings.find(name); if (i == all_strings.end()) return register_string(name); while (true) { vector<char> n(strlen(name)+10); snprintf(&n[0], n.size(), "%s %d", name, unique++); string_set::iterator i = all_strings.find(&n[0]); if (i == all_strings.end()) return register_string(&n[0]); } }
client::int_type client::recv_multi_bulk_reply_(string_set & out) { int_type length = recv_bulk_reply_(prefix_multi_bulk_reply); if (length == -1) throw key_error("no such key"); for (int_type i = 0; i < length; ++i) out.insert(recv_bulk_reply_()); return length; }
abstract_actor_ptr remote_actor_impl(stream_ptr_pair io, string_set expected) { CPPA_LOGF_TRACE("io{" << io.first.get() << ", " << io.second.get() << "}"); auto mm = get_middleman(); auto pinf = mm->node(); std::uint32_t process_id = pinf->process_id(); // throws on error io.second->write(&process_id, sizeof(std::uint32_t)); io.second->write(pinf->host_id().data(), pinf->host_id().size()); // deserialize: actor id, process id, node id, interface actor_id remote_aid; std::uint32_t peer_pid; node_id::host_id_type peer_node_id; std::uint32_t iface_size; std::set<std::string> iface; auto& in = io.first; // -> actor id in->read(&remote_aid, sizeof(actor_id)); // -> process id in->read(&peer_pid, sizeof(std::uint32_t)); // -> node id in->read(peer_node_id.data(), peer_node_id.size()); // -> interface in->read(&iface_size, sizeof(std::uint32_t)); if (iface_size > max_iface_size) { throw std::invalid_argument("Remote actor claims to have more than" +std::to_string(max_iface_size)+ " message types? Someone is trying" " something nasty!"); } std::vector<char> strbuf; for (std::uint32_t i = 0; i < iface_size; ++i) { std::uint32_t str_size; in->read(&str_size, sizeof(std::uint32_t)); if (str_size > max_iface_clause_size) { throw std::invalid_argument("Remote actor claims to have a" " reply_to<...>::with<...> clause with" " more than" +std::to_string(max_iface_clause_size)+ " characters? Someone is" " trying something nasty!"); } strbuf.reserve(str_size + 1); strbuf.resize(str_size); in->read(strbuf.data(), str_size); strbuf.push_back('\0'); iface.insert(std::string{strbuf.data()}); } // deserialization done, check interface if (iface != expected) { auto tostr = [](const std::set<std::string>& what) -> std::string { if (what.empty()) return "actor"; std::string tmp; tmp = "typed_actor<"; auto i = what.begin(); auto e = what.end(); tmp += *i++; while (i != e) tmp += *i++; tmp += ">"; return tmp; }; auto iface_str = tostr(iface); auto expected_str = tostr(expected); if (expected.empty()) { throw std::invalid_argument("expected remote actor to be a " "dynamically typed actor but found " "a strongly typed actor of type " + iface_str); } if (iface.empty()) { throw std::invalid_argument("expected remote actor to be a " "strongly typed actor of type " + expected_str + " but found a dynamically typed actor"); } throw std::invalid_argument("expected remote actor to be a " "strongly typed actor of type " + expected_str + " but found a strongly typed actor of type " + iface_str); } auto pinfptr = make_counted<node_id>(peer_pid, peer_node_id); if (*pinf == *pinfptr) { // this is a local actor, not a remote actor CPPA_LOGF_INFO("remote_actor() called to access a local actor"); auto ptr = get_actor_registry()->get(remote_aid); return ptr; } struct remote_actor_result { remote_actor_result* next; actor value; }; std::mutex qmtx; std::condition_variable qcv; intrusive::single_reader_queue<remote_actor_result> q; mm->run_later([mm, io, pinfptr, remote_aid, &q, &qmtx, &qcv] { CPPA_LOGC_TRACE("cppa", "remote_actor$create_connection", ""); auto pp = mm->get_peer(*pinfptr); CPPA_LOGF_INFO_IF(pp, "connection already exists (re-use old one)"); if (!pp) mm->new_peer(io.first, io.second, pinfptr); auto res = mm->get_namespace().get_or_put(pinfptr, remote_aid); q.synchronized_enqueue(qmtx, qcv, new remote_actor_result{0, res}); }); std::unique_ptr<remote_actor_result> result(q.synchronized_pop(qmtx, qcv)); CPPA_LOGF_DEBUG(CPPA_MARG(result, get)); return raw_access::get(result->value); }
/** Build the chroot at the path **/ bool WorkerBee::build_chroot(const std::string &path, uid_t user, gid_t group, string_set &executables, string_set &extra_dirs) { // Make the root path make_path(strdup(path.c_str())); string_set already_copied; std::string full_path; // The base directories string_set base_dirs; base_dirs.insert("bin"); base_dirs.insert("usr"); base_dirs.insert("var"); base_dirs.insert("lib"); base_dirs.insert("home"); base_dirs.insert("etc"); // Add the extra directories requested for (string_set::iterator dir = extra_dirs.begin(); dir != extra_dirs.end(); ++dir) base_dirs.insert(dir->c_str()); for (string_set::iterator dir = base_dirs.begin(); dir != base_dirs.end(); ++dir) { if ((*dir->c_str()) == '/') full_path = path + *dir; else full_path = path + '/' + *dir; // Make the paths make_path(full_path.c_str()); } // Build the root libraries for (string_set::iterator executable = executables.begin(); executable != executables.end(); ++executable) { // If we are pointed at an absolute path to a binary // then find the linked libraries of the executable // If it's not found, then find it, then look up the libraries std::string res_bin; if (abs_path(*executable)) res_bin = *executable; else { res_bin = find_binary(*executable); } // The libraries for the resolved binary bee_files_set *s_libs = libs_for(res_bin); // collect the libraries and copy them to the full path of the chroot for (bee_files_set::iterator bf = s_libs->begin(); bf != s_libs->end(); ++bf) { BeeFile bee = *bf; std::string s (bee.file_path()); // Don't copy if the file is already copied if (already_copied.count(s)) { } else { // If it is a symlink, then make a symlink, otherwise copy the file // If the library starts with a '/' then don't add one, otherwise, do // i.e. if libs/hi.so.1 turns into full_path/libs/hi.so.1 otherwise libs.so.1 turns into full_path/libs.so.1 if (s.c_str()[0] == '/') full_path = path + s.c_str(); else full_path = path + '/' + s.c_str(); if (bee.is_link()) { // make symlink make_path(dirname(strdup(full_path.c_str()))); if (symlink(bee.sym_origin().c_str(), full_path.c_str())) { fprintf(stderr, "Could not make a symlink: %s to %s because %s\n", bee.sym_origin().c_str(), full_path.c_str(), strerror(errno)); } } else { // Copy the file (recursively) cp_r(s, full_path); } // Change the permissions to match the original file struct stat file_stats = bee.file_stats(); mode_t mode = file_stats.st_mode; if (chown(full_path.c_str(), user, group) != 0) { fprintf(stderr, "Could not change owner of '%s' to %i\n", full_path.c_str(), user); } if (chmod(full_path.c_str(), mode) != 0) { fprintf(stderr, "Could not change permissions to '%s' %o\n", full_path.c_str(), mode); } // Add it to the already_copied set and move on already_copied.insert(s); } } // Copy the executables and make them executable std::string bin_path = path + '/' + res_bin; cp_r(res_bin.c_str(), bin_path.c_str()); if (chown(bin_path.c_str(), user, group) != 0) { fprintf(stderr, "Could not change owner of '%s' to %i\n", bin_path.c_str(), user); } if (chmod(bin_path.c_str(), S_IREAD|S_IEXEC|S_IXGRP|S_IRGRP|S_IWRITE)) { fprintf(stderr, "Could not change permissions to '%s' make it executable\n", bin_path.c_str()); } } return true; }
bool string_set::operator==(const string_set& a_) const { return _data.size() == a_._data.size() && std::equal(begin(), end(), a_.begin()); }