예제 #1
0
static void free_strings(string_set &s)
{
    for (string_set::iterator i=s.begin(); i!=s.end(); i++) {
        free((void*)*i);
    }
    s.clear();
}
예제 #2
0
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;
}
예제 #3
0
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]);
    }
}
예제 #4
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;
  }
예제 #5
0
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);
}
예제 #6
0
/** 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;
}
예제 #7
0
bool string_set::operator==(const string_set& a_) const
{
  return _data.size() == a_._data.size() &&
         std::equal(begin(), end(), a_.begin());
}