示例#1
0
文件: xdbfind.cpp 项目: harite/xgill
int main(int argc, const char **argv)
{
  plain_text.Enable();
  raw_tags.Enable();

  Vector<const char*> unspecified;
  bool parsed = Config::Parse(argc, argv, &unspecified);
  if (!parsed || unspecified.Size() != 2) {
    Config::PrintUsage(USAGE);
    return 1;
  }

  // we're only doing one access, we don't need the key cache
  Xdb::DisableKeyCache();

  AnalysisPrepare();

  const char *file = unspecified[0];
  const char *key = unspecified[1];

  Xdb *xdb = new Xdb(file, false, false, true);

  if (!xdb->Exists()) {
    delete xdb;
    return 0;
  }

  Buffer bkey((const uint8_t*) key, strlen(key) + 1);
  Buffer cdata;
  Buffer bdata;

  bool success = xdb->Find(&bkey, &cdata);
  if (success) {
    UncompressBufferInUse(&cdata, &bdata);
    size_t len = bdata.pos - bdata.base;

    if (plain_text.IsSpecified()) {
      for (size_t n = 0; n < len; n++)
        logout << (char) bdata.base[n];
      logout << endl;
    }
    else if (raw_tags.IsSpecified()) {
      size_t consumed = 0;
      while (consumed != len) {
        Buffer parse_data(bdata.base + consumed, len - consumed);
        parse_data.pos += len - consumed;

        size_t read_len = PrintPartialBuffer(&parse_data);

        if (read_len == 0)
          break;
        consumed += read_len;
      }
    }
    else {
      Buffer read_buf(bdata.base, len);
      while (read_buf.pos != read_buf.base + len) {
        HashObject *value = ReadSingleValue(&read_buf);
        logout << value << endl;
      }
    }
  }

  delete xdb;

  ClearBlockCaches();
  ClearMemoryCaches();
  AnalysisFinish(0);
}
int main(int argc, const char **argv)
{
  spawn_command.Enable();
  spawn_count.Enable();
  terminate_on_assert.Enable();

#ifdef USE_COUNT_ALLOCATOR
  memory_limit.Enable();
#endif

  modset_wait.Enable();

  Vector<const char*> unspecified;
  bool parsed = Config::Parse(argc, argv, &unspecified);
  if (!parsed || !unspecified.Empty()) {
    Config::PrintUsage(USAGE);
    return 1;
  }

  AnalysisPrepare();

  // use a different handler for termination signals.
  signal(SIGINT, termination_handler);
  signal(SIGTERM, termination_handler);

  // xmanager failures are unrecoverable.
  g_pause_assertions = true;
  if (terminate_on_assert.IsSpecified()) {
    g_pause_assertions = false;
  }

  int ret;

  event_init();

  server_socket = socket(PF_INET, SOCK_STREAM, 0);
  if (server_socket == -1) {
    logout << "ERROR: socket() failure: " << errno << endl;
    return 1;
  }

  struct sockaddr_in addr;
  memset(&addr, 0, sizeof(addr));

  ret = bind(server_socket, (sockaddr*) &addr, sizeof(addr));
  if (ret == -1) {
    logout << "ERROR: bind() failure: " << errno << endl;
    return 1;
  }

  int optval = 1;
  ret = setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
  if (ret == -1) {
    logout << "ERROR: setsockopt() failure: " << errno << endl;
    return 1;
  }

  int oldcode = fcntl(server_socket, F_GETFL, 0);
  if (oldcode == -1) {
    logout << "ERROR: fcntl() failure: " << errno << endl;
    return 1;
  }

  ret = fcntl(server_socket, F_SETFL, oldcode | O_NONBLOCK);
  if (ret == -1) {
    logout << "ERROR: fcntl() failure: " << errno << endl;
    return 1;
  }

  ret = listen(server_socket, 200);
  if (ret == -1) {
    logout << "ERROR: listen() failure: " << errno << endl;
    return 1;
  }

  event_set(&connect_event, server_socket, EV_READ | EV_PERSIST,
            handle_connect, NULL);

  ret = event_add(&connect_event, NULL);
  if (ret == -1) {
    logout << "ERROR: event_add() failure: " << errno << endl;
    return 1;
  }

  char hostbuf[256];
  unsigned short port;

  bool hostret = GetCurrentHost(server_socket, hostbuf, sizeof(hostbuf), &port);
  if (!hostret)
    return 1;

  logout << "Listening on " << hostbuf << ":" << port << endl << flush;

  // spawn the child processes if needed. this is done with a system()
  // call, in the expectation the call will either fork a new process
  // on this machine, or start up a process on another machine.
  if (spawn_count.IsSpecified()) {
    if (!spawn_command.IsSpecified()) {
      logout << "ERROR: -spawn-count must be used with -spawn-command" << endl;
      Config::PrintUsage(USAGE);
      return 1;
    }

    Buffer command_buf;
    BufferOutStream out(&command_buf);
    out << spawn_command.StringValue()
        << " -remote=" << hostbuf << ":" << port << '\0';
    const char *command = (const char*) command_buf.base;

    for (size_t ind = 0; ind < spawn_count.UIntValue(); ind++) {
      int ret = system(command);
      if (ret != 0) {
        logout << "ERROR: Spawn command failed: " << command << endl;
        return 1;
      }
      else {
        logout << "Command process spawned" << endl;
      }
      // we will not receive an initial transaction from these workers.
      received_initial++;
    }
  }

  ret = event_dispatch();

  if (ret == -1) {
    logout << "ERROR: event_dispatch() failure: " << errno << endl;
    return 1;
  }

  Assert(false);
}