<commit_before>/*
Copyright (c) 2017, Vadim Malyshev, lboss75@gmail.com
All rights reserved
*/

#include "stdafx.h"
#include "vds_cmd_app.h"
#include "http_router.h"
#include "user_manager.h"
#include "tcp_network_socket.h"
#include "http_request.h"
#include "http_serializer.h"
#include "http_client.h"
#include "http_response.h"
#include "http_multipart_request.h"
#include "http_mimetype.h"
#include <iomanip>

namespace vds {
  class http_multipart_request;
}

vds::vds_cmd_app::vds_cmd_app()
: file_upload_cmd_set_("Upload file", "Upload file on the network", "upload", "file"),
  file_download_cmd_set_("Download file", "Download file from the network", "download", "file"),
  channel_list_cmd_set_("Channel list", "List user channels", "list", "channel"),
  channel_create_cmd_set_("Channel create", "Create new channel", "create", "channel"),
  user_login_(
      "l",
      "login",
      "Login",
      "User login"),
  user_password_(
      "p",
      "password",
      "Password",
      "User password"),
  server_(
    "s",
    "server",
    "Server URL",
    "Server URL to connect"),
  channel_id_(
    "c",
    "channel",
    "Channel ID",
    "Channel identifier to send message"),
  message_(
    "m",
    "message",
    "Message",
    "Message"),
  attachment_(
    "a",
    "attachment",
    "File(s) names",
    "Comma separated file names"),
  output_folder_(
    "o",
    "output",
    "output folder",
    "Folder to store files"),
  output_format_(
    "f",
    "format",
    "Output format",
    "Output format (json)"
  ),
  channel_name_(
    "cn",
    "channel-name",
    "Channel name",
    "Name of channel"),
  channel_type_(
    "ct",
    "channel-type",
    "Channel type",
    "Type of channel") {
}

void vds::vds_cmd_app::main(const service_provider * sp)
{
  if (this->current_command_set_ == &this->file_upload_cmd_set_) {
    const auto session = this->login(sp);
    this->upload_file(sp, session);
  }
  else if(this->current_command_set_ == &this->channel_list_cmd_set_) {
    const auto session = this->login(sp);
    this->channel_list(sp, session);
  }
  else if (this->current_command_set_ == &this->channel_create_cmd_set_) {
    const auto session = this->login(sp);
    this->channel_create(sp, session);
  }
}

void vds::vds_cmd_app::register_services(vds::service_registrator& registrator)
{
  base_class::register_services(registrator);
  registrator.add(this->mt_service_);
  registrator.add(this->task_manager_);
  registrator.add(this->network_service_);
}

void vds::vds_cmd_app::register_command_line(command_line & cmd_line)
{
  base_class::register_command_line(cmd_line);

  cmd_line.add_command_set(this->file_upload_cmd_set_);
  this->file_upload_cmd_set_.required(this->user_login_);
  this->file_upload_cmd_set_.required(this->user_password_);
  this->file_upload_cmd_set_.optional(this->server_);
  this->file_upload_cmd_set_.required(this->channel_id_);
  this->file_upload_cmd_set_.optional(this->message_);
  this->file_upload_cmd_set_.required(this->attachment_);
  this->file_upload_cmd_set_.optional(this->output_folder_);

  cmd_line.add_command_set(this->file_download_cmd_set_);
  this->file_download_cmd_set_.required(this->user_login_);
  this->file_download_cmd_set_.required(this->user_password_);
  this->file_download_cmd_set_.optional(this->server_);
  this->file_download_cmd_set_.required(this->channel_id_);
  this->file_download_cmd_set_.optional(this->message_);
  this->file_download_cmd_set_.required(this->attachment_);
  this->file_download_cmd_set_.optional(this->output_folder_);

  cmd_line.add_command_set(this->channel_list_cmd_set_);
  this->channel_list_cmd_set_.required(this->user_login_);
  this->channel_list_cmd_set_.required(this->user_password_);
  this->channel_list_cmd_set_.optional(this->server_);
  this->channel_list_cmd_set_.optional(this->output_format_);

  cmd_line.add_command_set(this->channel_create_cmd_set_);
  this->channel_create_cmd_set_.required(this->user_login_);
  this->channel_create_cmd_set_.required(this->user_password_);
  this->channel_create_cmd_set_.optional(this->server_);
  this->channel_create_cmd_set_.optional(this->channel_name_);
  this->channel_create_cmd_set_.optional(this->channel_type_);

  //cmd_line.add_command_set(this->server_init_command_set_);
  //this->server_init_command_set_.required(this->user_login_);
  //this->server_init_command_set_.required(this->user_password_);
  //this->server_init_command_set_.optional(this->node_name_);
  //this->server_init_command_set_.optional(this->port_);
}

void vds::vds_cmd_app::start_services(service_registrator & registrator, service_provider * sp)
{
  base_class::start_services(registrator, sp);
}

bool vds::vds_cmd_app::need_demonize()
{
  return false;
}

std::string vds::vds_cmd_app::login(const service_provider * sp)
{
  auto server = this->server_.value().empty() ? "tcp://localhost:8050" : this->server_.value();

  auto s = tcp_network_socket::connect(sp, network_address::parse(server));
  auto[reader, writer] = s->start(sp);

  auto client = std::make_shared<http_client>();
  client->start(reader, writer).detach();

  std::string session;
  client->send(http_request::create(
    "GET",
    "/api/login?login=" + url_encode::encode(this->user_login_.value())
    + "&password=" + url_encode::encode(this->user_password_.value())).get_message(),
    [server, &session](const http_message response) -> async_task<void> {

    http_response login_response(response);

    if (login_response.code() != http_response::HTTP_OK) {
      throw std::runtime_error("Login failed");
    }

    auto body = json_parser::parse(
      server + "/api/login",
      co_await response.body()->read_all());

    auto body_object = dynamic_cast<const json_object *>(body.get());

    std::string value;
    body_object->get_property("state", value);

    if ("successful" != value) {
      co_return;
    }

    body_object->get_property("session", session);
  }).get();

  return session;
}

void vds::vds_cmd_app::upload_file(const service_provider * sp, const std::string & session) {
  auto server = this->server_.value().empty() ? "tcp://localhost:8050" : this->server_.value();

  auto s = tcp_network_socket::connect(sp, network_address::parse(server));
  auto[reader, writer] = s->start(sp);

  auto client = std::make_shared<http_client>();
  client->start(reader, writer).detach();

  http_multipart_request request(
    "POST",
    "/api/upload?session=" + url_encode::encode(session));

  request.add_string("channel_id", this->channel_id_.value());
  if (!this->message_.value().empty()) {
    request.add_string("message", this->message_.value());
  }

  filename fn(this->attachment_.value());

  auto mimetype = http_mimetype::mimetype(fn);
  if(mimetype.empty()) {
    mimetype = "application/octet-stream";
  }
  request.add_file("attachment", fn, fn.name(), mimetype);

  client->send(request.get_message(),
    [server](const http_message response) -> async_task<void> {

    if (http_response(response).code() != http_response::HTTP_OK) {
      throw std::runtime_error("Upload failed");
    }

    co_return;
  }).get();
}

void vds::vds_cmd_app::channel_list(const service_provider* sp, const std::string& session) {
  auto server = this->server_.value().empty() ? "tcp://localhost:8050" : this->server_.value();

  auto s = tcp_network_socket::connect(sp, network_address::parse(server));
  auto[reader, writer] = s->start(sp);

  auto client = std::make_shared<http_client>();
  client->start(reader, writer).detach();

  client->send(http_request::create(
    "GET",
    "/api/channels?session=" + url_encode::encode(session)).get_message(),
    [server, this](const http_message response) -> async_task<void> {

    if (http_response(response).code() != http_response::HTTP_OK) {
      throw std::runtime_error("Query channels failed");
    }

    if (this->output_format_.value() == "json") {
      std::cout << co_await response.body()->read_all() << std::endl;
    }
    else {
      auto body = json_parser::parse(
        server + "/api/channels",
        co_await response.body()->read_all());

      std::cout << std::setw(44) << std::left << "ID" << "|"
      << std::setw(15) << std::left << "Type" << "|"
      << "Name" << std::endl;

      auto body_array = dynamic_cast<const json_array *>(body.get());
      for(size_t i = 0; i < body_array->size(); ++i) {
        auto item = dynamic_cast<const json_object *>(body_array->get(i).get());

        std::string value;
        item->get_property("object_id", value);
        std::cout << std::setw(44) << value << "|";

        item->get_property("type", value);
        std::cout << std::setw(15) << std::left << value << "|";

        item->get_property("name", value);
        std::cout << value << std::endl;
      }
    }
  }).get();
}

void vds::vds_cmd_app::channel_create(const service_provider* sp, const std::string& session) {
  auto server = this->server_.value().empty() ? "tcp://localhost:8050" : this->server_.value();

  auto s = tcp_network_socket::connect(sp, network_address::parse(server));
  auto[reader, writer] = s->start(sp);

  auto client = std::make_shared<http_client>();
  client->start(reader, writer).detach();

  client->send(http_request::create(
    "POST",
    "/api/channels?session=" + url_encode::encode(session)
    + "&name=" + url_encode::encode(this->channel_name_.value())
    + "&type=" + url_encode::encode(this->channel_type_.value())
    ).get_message(),
    [server, this](const http_message response) -> async_task<void> {

    if (http_response(response).code() != http_response::HTTP_OK) {
      throw std::runtime_error("Create channel failed");
    }

    co_return;
  }).get();
}
<commit_msg>add error message<commit_after>/*
Copyright (c) 2017, Vadim Malyshev, lboss75@gmail.com
All rights reserved
*/

#include "stdafx.h"
#include "vds_cmd_app.h"
#include "http_router.h"
#include "user_manager.h"
#include "tcp_network_socket.h"
#include "http_request.h"
#include "http_serializer.h"
#include "http_client.h"
#include "http_response.h"
#include "http_multipart_request.h"
#include "http_mimetype.h"
#include <iomanip>

namespace vds {
  class http_multipart_request;
}

vds::vds_cmd_app::vds_cmd_app()
: file_upload_cmd_set_("Upload file", "Upload file on the network", "upload", "file"),
  file_download_cmd_set_("Download file", "Download file from the network", "download", "file"),
  channel_list_cmd_set_("Channel list", "List user channels", "list", "channel"),
  channel_create_cmd_set_("Channel create", "Create new channel", "create", "channel"),
  user_login_(
      "l",
      "login",
      "Login",
      "User login"),
  user_password_(
      "p",
      "password",
      "Password",
      "User password"),
  server_(
    "s",
    "server",
    "Server URL",
    "Server URL to connect"),
  channel_id_(
    "c",
    "channel",
    "Channel ID",
    "Channel identifier to send message"),
  message_(
    "m",
    "message",
    "Message",
    "Message"),
  attachment_(
    "a",
    "attachment",
    "File(s) names",
    "Comma separated file names"),
  output_folder_(
    "o",
    "output",
    "output folder",
    "Folder to store files"),
  output_format_(
    "f",
    "format",
    "Output format",
    "Output format (json)"
  ),
  channel_name_(
    "cn",
    "channel-name",
    "Channel name",
    "Name of channel"),
  channel_type_(
    "ct",
    "channel-type",
    "Channel type",
    "Type of channel") {
}

void vds::vds_cmd_app::main(const service_provider * sp)
{
  if (this->current_command_set_ == &this->file_upload_cmd_set_) {
    const auto session = this->login(sp);
    this->upload_file(sp, session);
  }
  else if(this->current_command_set_ == &this->channel_list_cmd_set_) {
    const auto session = this->login(sp);
    this->channel_list(sp, session);
  }
  else if (this->current_command_set_ == &this->channel_create_cmd_set_) {
    const auto session = this->login(sp);
    this->channel_create(sp, session);
  }
}

void vds::vds_cmd_app::register_services(vds::service_registrator& registrator)
{
  base_class::register_services(registrator);
  registrator.add(this->mt_service_);
  registrator.add(this->task_manager_);
  registrator.add(this->network_service_);
}

void vds::vds_cmd_app::register_command_line(command_line & cmd_line)
{
  base_class::register_command_line(cmd_line);

  cmd_line.add_command_set(this->file_upload_cmd_set_);
  this->file_upload_cmd_set_.required(this->user_login_);
  this->file_upload_cmd_set_.required(this->user_password_);
  this->file_upload_cmd_set_.optional(this->server_);
  this->file_upload_cmd_set_.required(this->channel_id_);
  this->file_upload_cmd_set_.optional(this->message_);
  this->file_upload_cmd_set_.required(this->attachment_);
  this->file_upload_cmd_set_.optional(this->output_folder_);

  cmd_line.add_command_set(this->file_download_cmd_set_);
  this->file_download_cmd_set_.required(this->user_login_);
  this->file_download_cmd_set_.required(this->user_password_);
  this->file_download_cmd_set_.optional(this->server_);
  this->file_download_cmd_set_.required(this->channel_id_);
  this->file_download_cmd_set_.optional(this->message_);
  this->file_download_cmd_set_.required(this->attachment_);
  this->file_download_cmd_set_.optional(this->output_folder_);

  cmd_line.add_command_set(this->channel_list_cmd_set_);
  this->channel_list_cmd_set_.required(this->user_login_);
  this->channel_list_cmd_set_.required(this->user_password_);
  this->channel_list_cmd_set_.optional(this->server_);
  this->channel_list_cmd_set_.optional(this->output_format_);

  cmd_line.add_command_set(this->channel_create_cmd_set_);
  this->channel_create_cmd_set_.required(this->user_login_);
  this->channel_create_cmd_set_.required(this->user_password_);
  this->channel_create_cmd_set_.optional(this->server_);
  this->channel_create_cmd_set_.optional(this->channel_name_);
  this->channel_create_cmd_set_.optional(this->channel_type_);

  //cmd_line.add_command_set(this->server_init_command_set_);
  //this->server_init_command_set_.required(this->user_login_);
  //this->server_init_command_set_.required(this->user_password_);
  //this->server_init_command_set_.optional(this->node_name_);
  //this->server_init_command_set_.optional(this->port_);
}

void vds::vds_cmd_app::start_services(service_registrator & registrator, service_provider * sp)
{
  base_class::start_services(registrator, sp);
}

bool vds::vds_cmd_app::need_demonize()
{
  return false;
}

std::string vds::vds_cmd_app::login(const service_provider * sp)
{
  auto server = this->server_.value().empty() ? "tcp://localhost:8050" : this->server_.value();

  auto s = tcp_network_socket::connect(sp, network_address::parse(server));
  auto[reader, writer] = s->start(sp);

  auto client = std::make_shared<http_client>();
  client->start(reader, writer).detach();

  std::string session;
  client->send(http_request::create(
    "GET",
    "/api/login?login=" + url_encode::encode(this->user_login_.value())
    + "&password=" + url_encode::encode(this->user_password_.value())).get_message(),
    [server, &session](const http_message response) -> async_task<void> {

    http_response login_response(response);

    if (login_response.code() != http_response::HTTP_OK) {
      throw std::runtime_error("Login failed");
    }

    auto body = json_parser::parse(
      server + "/api/login",
      co_await response.body()->read_all());

    auto body_object = dynamic_cast<const json_object *>(body.get());

    std::string value;
    body_object->get_property("state", value);

    if ("successful" != value) {
      co_return;
    }

    body_object->get_property("session", session);
  }).get();

  return session;
}

void vds::vds_cmd_app::upload_file(const service_provider * sp, const std::string & session) {
  auto server = this->server_.value().empty() ? "tcp://localhost:8050" : this->server_.value();

  auto s = tcp_network_socket::connect(sp, network_address::parse(server));
  auto[reader, writer] = s->start(sp);

  auto client = std::make_shared<http_client>();
  client->start(reader, writer).detach();

  http_multipart_request request(
    "POST",
    "/api/upload?session=" + url_encode::encode(session));

  request.add_string("channel_id", this->channel_id_.value());
  if (!this->message_.value().empty()) {
    request.add_string("message", this->message_.value());
  }

  filename fn(this->attachment_.value());

  auto mimetype = http_mimetype::mimetype(fn);
  if(mimetype.empty()) {
    mimetype = "application/octet-stream";
  }
  request.add_file("attachment", fn, fn.name(), mimetype);

  client->send(request.get_message(),
    [server](const http_message response) -> async_task<void> {

    if (http_response(response).code() != http_response::HTTP_OK) {
      throw std::runtime_error("Upload failed");
    }

    co_return;
  }).get();
}

void vds::vds_cmd_app::channel_list(const service_provider* sp, const std::string& session) {
  auto server = this->server_.value().empty() ? "tcp://localhost:8050" : this->server_.value();

  auto s = tcp_network_socket::connect(sp, network_address::parse(server));
  auto[reader, writer] = s->start(sp);

  auto client = std::make_shared<http_client>();
  client->start(reader, writer).detach();

  client->send(http_request::create(
    "GET",
    "/api/channels?session=" + url_encode::encode(session)).get_message(),
    [server, this](const http_message response) -> async_task<void> {

    if (http_response(response).code() != http_response::HTTP_OK) {
      throw std::runtime_error("Query channels failed " + http_response(response).comment());
    }

    if (this->output_format_.value() == "json") {
      std::cout << co_await response.body()->read_all() << std::endl;
    }
    else {
      auto body = json_parser::parse(
        server + "/api/channels",
        co_await response.body()->read_all());

      std::cout << std::setw(44) << std::left << "ID" << "|"
      << std::setw(15) << std::left << "Type" << "|"
      << "Name" << std::endl;

      auto body_array = dynamic_cast<const json_array *>(body.get());
      for(size_t i = 0; i < body_array->size(); ++i) {
        auto item = dynamic_cast<const json_object *>(body_array->get(i).get());

        std::string value;
        item->get_property("object_id", value);
        std::cout << std::setw(44) << value << "|";

        item->get_property("type", value);
        std::cout << std::setw(15) << std::left << value << "|";

        item->get_property("name", value);
        std::cout << value << std::endl;
      }
    }
  }).get();
}

void vds::vds_cmd_app::channel_create(const service_provider* sp, const std::string& session) {
  auto server = this->server_.value().empty() ? "tcp://localhost:8050" : this->server_.value();

  auto s = tcp_network_socket::connect(sp, network_address::parse(server));
  auto[reader, writer] = s->start(sp);

  auto client = std::make_shared<http_client>();
  client->start(reader, writer).detach();

  client->send(http_request::create(
    "POST",
    "/api/channels?session=" + url_encode::encode(session)
    + "&name=" + url_encode::encode(this->channel_name_.value())
    + "&type=" + url_encode::encode(this->channel_type_.value())
    ).get_message(),
    [server, this](const http_message response) -> async_task<void> {

    if (http_response(response).code() != http_response::HTTP_OK) {
      throw std::runtime_error("Create channel failed");
    }

    co_return;
  }).get();
}
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/platform_file.h"

#include <fcntl.h>
#include <errno.h>

#include "base/logging.h"
#include "base/string_util.h"

namespace base {

// TODO(erikkay): does it make sense to support PLATFORM_FILE_EXCLUSIVE_* here?
PlatformFile CreatePlatformFile(const std::wstring& name,
                                int flags,
                                bool* created) {
  int open_flags = 0;
  if (flags & PLATFORM_FILE_CREATE)
    open_flags = O_CREAT | O_EXCL;

  if (flags & PLATFORM_FILE_CREATE_ALWAYS) {
    DCHECK(!open_flags);
    open_flags = O_CREAT | O_TRUNC;
  }

  if (!open_flags && !(flags & PLATFORM_FILE_OPEN) &&
      !(flags & PLATFORM_FILE_OPEN_ALWAYS)) {
    NOTREACHED();
    errno = ENOTSUP;
    return INVALID_HANDLE_VALUE;
  }

  if (flags & PLATFORM_FILE_WRITE && flags & PLATFORM_FILE_READ) {
    open_flags |= O_RDWR;
  } else if (flags & PLATFORM_FILE_WRITE) {
    open_flags |= O_WRONLY;
  } else if (!(flags & PLATFORM_FILE_READ)) {
    NOTREACHED();
  }

  DCHECK(O_RDONLY == 0);

  int descriptor = open(WideToUTF8(name).c_str(), open_flags,
                        S_IRUSR | S_IWUSR);

  if (flags & PLATFORM_FILE_OPEN_ALWAYS) {
    if (descriptor > 0) {
      if (created)
        *created = false;
    } else {
      open_flags |= O_CREAT;
      descriptor = open(WideToUTF8(name).c_str(), open_flags,
                        S_IRUSR | S_IWUSR);
      if (created && descriptor > 0)
        *created = true;
    }
  }

  return descriptor;
}

}  // namespace base
<commit_msg>quick build fix for Linux<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/platform_file.h"

#include <fcntl.h>
#include <errno.h>

#include "base/logging.h"
#include "base/string_util.h"

namespace base {

// TODO(erikkay): does it make sense to support PLATFORM_FILE_EXCLUSIVE_* here?
PlatformFile CreatePlatformFile(const std::wstring& name,
                                int flags,
                                bool* created) {
  int open_flags = 0;
  if (flags & PLATFORM_FILE_CREATE)
    open_flags = O_CREAT | O_EXCL;

  if (flags & PLATFORM_FILE_CREATE_ALWAYS) {
    DCHECK(!open_flags);
    open_flags = O_CREAT | O_TRUNC;
  }

  if (!open_flags && !(flags & PLATFORM_FILE_OPEN) &&
      !(flags & PLATFORM_FILE_OPEN_ALWAYS)) {
    NOTREACHED();
    errno = ENOTSUP;
    return kInvalidPlatformFileValue;
  }

  if (flags & PLATFORM_FILE_WRITE && flags & PLATFORM_FILE_READ) {
    open_flags |= O_RDWR;
  } else if (flags & PLATFORM_FILE_WRITE) {
    open_flags |= O_WRONLY;
  } else if (!(flags & PLATFORM_FILE_READ)) {
    NOTREACHED();
  }

  DCHECK(O_RDONLY == 0);

  int descriptor = open(WideToUTF8(name).c_str(), open_flags,
                        S_IRUSR | S_IWUSR);

  if (flags & PLATFORM_FILE_OPEN_ALWAYS) {
    if (descriptor > 0) {
      if (created)
        *created = false;
    } else {
      open_flags |= O_CREAT;
      descriptor = open(WideToUTF8(name).c_str(), open_flags,
                        S_IRUSR | S_IWUSR);
      if (created && descriptor > 0)
        *created = true;
    }
  }

  return descriptor;
}

}  // namespace base
<|endoftext|>


<commit_before>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
// $Id: exception.C,v 1.36 2004/09/01 12:38:12 amoll Exp $
//

#include <BALL/COMMON/exception.h>
#include <BALL/COMMON/logStream.h>
#include <BALL/DATATYPE/string.h>

#include <iostream>
#include <typeinfo>
#include <exception>
#include <stdio.h>
#include <stdlib.h>	// for getenv in terminate()
#include <sys/types.h>
#include <signal.h> // for SIGSEGV and kill

#ifdef BALL_HAS_UNISTD_H
#	include <unistd.h> // fot getpid
#endif
#ifdef BALL_HAS_PROCESS_H
#	include <process.h>
#endif

#define BALL_CORE_DUMP_ENVNAME "BALL_DUMP_CORE"

#define DEF_EXCEPTION(a,b) \
	a :: a (const char* file, int line) throw()\
		: GeneralException(file, line, #a, b)\
	{\
	}\

using std::string;
using std::endl;

namespace BALL
{

	namespace Exception
	{

			GeneralException::GeneralException()
				throw()
				:	file_("?"),
					line_(-1),
					name_("GeneralException"),
					message_("unspecified error")
			{
				globalHandler.set(file_, line_, String(name_), String(message_));
			}

			GeneralException::GeneralException(const char* file, int line, const String& name, const String& message)
				throw()
				:	file_(file),
					line_(line),
					name_(name),
					message_(message)
			{
				globalHandler.set(file_, line_, name_, message_);
			}

			GeneralException::GeneralException(const char* file, int line)
				throw()
				:	file_(file),
					line_(line),
					name_("GeneralException"),
					message_("unknown error")
			{
				globalHandler.set(file_, line_, name_, message_);
			}

			GeneralException::GeneralException(const GeneralException& exception)
				throw()
				:	std::exception(exception),
					file_(exception.file_),
					line_(exception.line_),
					name_(exception.name_),
					message_(exception.message_)
			{
			}

			GeneralException::~GeneralException()
				throw()
			{
			}

			const char* GeneralException::getName() const
				throw()
			{
				return name_.c_str();
			}

			const char* GeneralException::getMessage() const
				throw()
			{
				return message_.c_str();
			}

			void GeneralException::setMessage(const std::string& message)
				throw()
			{
				message_ = message;
			}

			const char* GeneralException::getFile() const
				throw()
			{
				return file_;
			}

			int GeneralException::getLine() const
				throw()
			{
				return line_;
			}

			IndexUnderflow::IndexUnderflow(const char* file, int line, Index index, Size size)
				throw()
				: GeneralException(file, line, "IndexUnderflow", ""),
					size_(size),
					index_(index)
			{
				message_ = "the given index was too small: ";
				char buf[40];

				sprintf(buf, "%ld", (long)index);
				message_ += buf;
				message_ += " (size = ";

				sprintf(buf, "%ld", (long)size);
				message_ += buf;
				message_ += ")";

				globalHandler.setMessage(message_);
			}

			IndexOverflow::IndexOverflow(const char* file, int line, Index index, Size size)
				throw()
				:	GeneralException(file, line, "IndexOverflow", "an index was too large"),
					size_(size),
					index_(index)
			{
				message_ = "the given index was too large: ";
				char buf[40];

				sprintf(buf, "%ld", (long)index);
				message_ += buf;
				message_ += " (size = ";

				sprintf(buf, "%ld", (long)size);
				message_ += buf;
				message_ += ")";

				globalHandler.setMessage(message_);
			}

			OutOfMemory::OutOfMemory(const char* file, int line, Size size)
				throw()
				:	GeneralException(file, line, "OutOfMemory", "a memory allocation failed"),
					size_(size)
			{
				message_ = "unable to allocate enough memory (size = ";
				char buf[40];

				sprintf(buf, "%ld", (long)size_);
				message_ += buf;
				message_ += " bytes) ";

				globalHandler.setMessage(message_);
			}

			OutOfMemory::~OutOfMemory()
				throw()
			{
			}

			SizeUnderflow::SizeUnderflow(const char* file, int line, Size size)
				throw()
				:	GeneralException(file, line, "SizeUnderflow", ""),
					size_(size)
			{
				message_ = "the given size was too small: ";
				char buf[40];
				sprintf(buf, "%ld", (long)size);

				message_ += buf;
				globalHandler.setMessage(message_);
			}

			InvalidSize::InvalidSize(const char* file, int line, Size size)
				throw()
				:	GeneralException(file, line, "InvalidSize", ""),
					size_(size)
			{
				message_ = "the given size was not expected: ";
				char buf[40];
				sprintf(buf, "%ld", (long)size);

				message_ += buf;
				globalHandler.setMessage(message_);
			}

			IllegalPosition::IllegalPosition(const char* file, int line, float x, float y, float z)
				throw()
				:	GeneralException(file, line, "IllegalPosition:", "")
			{
				char buf1[40];
				sprintf(buf1, "%f", x);
				char buf2[40];
				sprintf(buf2, "%f", y);
				char buf3[40];
				sprintf(buf3, "%f", z);

				message_ += "(";
				message_ += buf1;
				message_ += ",";
				message_ += buf2;
				message_ += ",";
				message_ += buf3;
				message_ += ")";
				globalHandler.setMessage(message_);
			}

			ParseError::ParseError(const char* file, int line,
					const String& expression, const String& message)
				throw()
				: GeneralException(file, line, "Parse Error", "")
			{

				message_ += message;
				message_ += " in ";
				message_ += expression;
				globalHandler.setMessage(message_);
			}

			Precondition::Precondition(const char* file, int line, const char* condition)
				throw()
				: GeneralException(file, line, "Precondition failed", "")
			{
				message_ += std::string(condition);
				globalHandler.setMessage(message_);
			}

			Postcondition::Postcondition(const char* file, int line, const char* condition)
				throw()
				: GeneralException(file, line, "Postcondition failed", "")
			{
				message_ += std::string(condition);
				globalHandler.setMessage(message_);
			}

			FileNotFound::FileNotFound(const char* file, int line, const String& filename)
				throw()
				:	GeneralException(file, line, "FileNotFound", ""),
					filename_(filename)
			{
				message_ = "the file " + filename + " could not be found";
				globalHandler.setMessage(message_);
			}

			FileNotFound::~FileNotFound()
				throw()
			{
			}

			String FileNotFound::getFilename() const
				throw()
			{
				return filename_;
			}

			InvalidFormat::InvalidFormat(const char* file, int line, const String& s)
				throw()
				:	GeneralException(file, line, "InvalidFormat", ""),
					format_(s)
			{
				message_ = "problem converting '";
				message_.append(s + "' to a number.");

				globalHandler.setMessage(message_);
			}

			InvalidFormat::~InvalidFormat()
				throw()
			{
			}

			InvalidOption::InvalidOption(const char* file, int line, String option)
				throw()
				: GeneralException(file, line, "Invalid option: ", option)
			{
			}

			DEF_EXCEPTION(DivisionByZero, "a division by zero was requested")

			DEF_EXCEPTION(InvalidRange, "the range of the operation was invalid")

			DEF_EXCEPTION(OutOfRange, "the argument was not in range")

			DEF_EXCEPTION(NullPointer, "a null pointer was specified")

			DEF_EXCEPTION(InvalidIterator, "the iterator is invalid - probably it is not bound to a container")

			DEF_EXCEPTION(IncompatibleIterators, "the iterator could not be assigned because it is bound to a different container")

			DEF_EXCEPTION(NotImplemented, "this method has not been implemented yet. Feel free to complain about it!")

			DEF_EXCEPTION(IllegalSelfOperation, "cannot perform operation on the same object")

			DEF_EXCEPTION(IllegalTreeOperation, "an illegal tree operation was requested")

			DEF_EXCEPTION(BufferOverflow, "the maximum buffersize has been reached")

			DEF_EXCEPTION(OutOfGrid, "a point was outside a grid")

			GlobalExceptionHandler::GlobalExceptionHandler()
				throw()
			{
				std::set_terminate(terminate);
				std::set_unexpected(terminate);
				std::set_new_handler(newHandler);
			}

			void GlobalExceptionHandler::newHandler()
				throw(Exception::OutOfMemory)
			{
				throw Exception::OutOfMemory(__FILE__, __LINE__);
			}

			void GlobalExceptionHandler::terminate()
				throw()
			{
				// add cerr to the log stream
				// and write all available information on
				// the exception to the log stream (potentially with an assigned file!)
				// and cerr

				Log.insert(std::cerr);
				Log.error() << endl;
				Log.error() << "---------------------------------------------------" << endl;
				Log.error() << "FATAL: uncaught exception!" << endl;
				Log.error() << "---------------------------------------------------" << endl;
				if ((line_ != -1) && (name_ != "unknown"))
				{
					Log.error() << "last entry in the exception handler: " << endl;
					Log.error() << "exception of type " << name_.c_str() << " occured in line "
											<< line_ << " of " << file_.c_str() << endl;
					Log.error() << "error message: " << message_.c_str() << endl;
				}
				Log.error() << "---------------------------------------------------" << endl;

				// if the environment variable declared in BALL_CORE_DUMP_ENVNAME
				// is set, provoke a core dump (this is helpful to get s stack traceback)
				if (getenv(BALL_CORE_DUMP_ENVNAME) != 0)
				{
					#ifdef BALL_HAS_KILL
						Log.error() << "dumping core file.... (to avoid this, unset " << BALL_CORE_DUMP_ENVNAME
									<< " in your environment)" << endl;
						// provoke a core dump
						kill(getpid(), SIGSEGV);
					#endif
				}

				// otherwise exit cleanly
				exit(1);
			}

			void GlobalExceptionHandler::set
				(const String& file, int line,
				 const String& name, const String& message)
				throw()
			{
				name_ = name;
				line_ = line;
				message_ = message;
				file_ = file;
			}

			void GlobalExceptionHandler::setName(const String& name)
				throw()
			{
				name_ = name;
			}

			void GlobalExceptionHandler::setMessage(const String& message)
				throw()
			{
				message_ = message;
			}

			void GlobalExceptionHandler::setFile(const String& file)
				throw()
			{
				file_ = file;
			}

			void GlobalExceptionHandler::setLine(int line)
				throw()
			{
				line_ = line;
			}

			std::string	GlobalExceptionHandler::name_			= "unknown exception";
			int					GlobalExceptionHandler::line_			= -1;
			std::string	GlobalExceptionHandler::message_	= " - ";
			std::string	GlobalExceptionHandler::file_			= "unknown";

			// create a global instance of the exception handler
			GlobalExceptionHandler globalHandler;

	} // namespace Exception

	std::ostream& operator << (std::ostream& os, const Exception::GeneralException& e)
	{
		os << e.getName() << " @ " << e.getFile() << ":" << e.getLine() << ": " << e.getMessage();

		return os;
	}

} // namespace BALL
<commit_msg>had to move TooManyErrors here to prevent problems with sip<commit_after>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
// $Id: exception.C,v 1.37 2004/12/27 18:08:51 amoll Exp $
//

#include <BALL/COMMON/exception.h>
#include <BALL/COMMON/logStream.h>
#include <BALL/DATATYPE/string.h>

#include <iostream>
#include <typeinfo>
#include <exception>
#include <stdio.h>
#include <stdlib.h>	// for getenv in terminate()
#include <sys/types.h>
#include <signal.h> // for SIGSEGV and kill

#ifdef BALL_HAS_UNISTD_H
#	include <unistd.h> // fot getpid
#endif
#ifdef BALL_HAS_PROCESS_H
#	include <process.h>
#endif

#define BALL_CORE_DUMP_ENVNAME "BALL_DUMP_CORE"

#define DEF_EXCEPTION(a,b) \
	a :: a (const char* file, int line) throw()\
		: GeneralException(file, line, #a, b)\
	{\
	}\

using std::string;
using std::endl;

namespace BALL
{

	namespace Exception
	{

			GeneralException::GeneralException()
				throw()
				:	file_("?"),
					line_(-1),
					name_("GeneralException"),
					message_("unspecified error")
			{
				globalHandler.set(file_, line_, String(name_), String(message_));
			}

			GeneralException::GeneralException(const char* file, int line, const String& name, const String& message)
				throw()
				:	file_(file),
					line_(line),
					name_(name),
					message_(message)
			{
				globalHandler.set(file_, line_, name_, message_);
			}

			GeneralException::GeneralException(const char* file, int line)
				throw()
				:	file_(file),
					line_(line),
					name_("GeneralException"),
					message_("unknown error")
			{
				globalHandler.set(file_, line_, name_, message_);
			}

			GeneralException::GeneralException(const GeneralException& exception)
				throw()
				:	std::exception(exception),
					file_(exception.file_),
					line_(exception.line_),
					name_(exception.name_),
					message_(exception.message_)
			{
			}

			GeneralException::~GeneralException()
				throw()
			{
			}

			const char* GeneralException::getName() const
				throw()
			{
				return name_.c_str();
			}

			const char* GeneralException::getMessage() const
				throw()
			{
				return message_.c_str();
			}

			void GeneralException::setMessage(const std::string& message)
				throw()
			{
				message_ = message;
			}

			const char* GeneralException::getFile() const
				throw()
			{
				return file_;
			}

			int GeneralException::getLine() const
				throw()
			{
				return line_;
			}

			IndexUnderflow::IndexUnderflow(const char* file, int line, Index index, Size size)
				throw()
				: GeneralException(file, line, "IndexUnderflow", ""),
					size_(size),
					index_(index)
			{
				message_ = "the given index was too small: ";
				char buf[40];

				sprintf(buf, "%ld", (long)index);
				message_ += buf;
				message_ += " (size = ";

				sprintf(buf, "%ld", (long)size);
				message_ += buf;
				message_ += ")";

				globalHandler.setMessage(message_);
			}

			IndexOverflow::IndexOverflow(const char* file, int line, Index index, Size size)
				throw()
				:	GeneralException(file, line, "IndexOverflow", "an index was too large"),
					size_(size),
					index_(index)
			{
				message_ = "the given index was too large: ";
				char buf[40];

				sprintf(buf, "%ld", (long)index);
				message_ += buf;
				message_ += " (size = ";

				sprintf(buf, "%ld", (long)size);
				message_ += buf;
				message_ += ")";

				globalHandler.setMessage(message_);
			}

			OutOfMemory::OutOfMemory(const char* file, int line, Size size)
				throw()
				:	GeneralException(file, line, "OutOfMemory", "a memory allocation failed"),
					size_(size)
			{
				message_ = "unable to allocate enough memory (size = ";
				char buf[40];

				sprintf(buf, "%ld", (long)size_);
				message_ += buf;
				message_ += " bytes) ";

				globalHandler.setMessage(message_);
			}

			OutOfMemory::~OutOfMemory()
				throw()
			{
			}

			SizeUnderflow::SizeUnderflow(const char* file, int line, Size size)
				throw()
				:	GeneralException(file, line, "SizeUnderflow", ""),
					size_(size)
			{
				message_ = "the given size was too small: ";
				char buf[40];
				sprintf(buf, "%ld", (long)size);

				message_ += buf;
				globalHandler.setMessage(message_);
			}

			InvalidSize::InvalidSize(const char* file, int line, Size size)
				throw()
				:	GeneralException(file, line, "InvalidSize", ""),
					size_(size)
			{
				message_ = "the given size was not expected: ";
				char buf[40];
				sprintf(buf, "%ld", (long)size);

				message_ += buf;
				globalHandler.setMessage(message_);
			}

			IllegalPosition::IllegalPosition(const char* file, int line, float x, float y, float z)
				throw()
				:	GeneralException(file, line, "IllegalPosition:", "")
			{
				char buf1[40];
				sprintf(buf1, "%f", x);
				char buf2[40];
				sprintf(buf2, "%f", y);
				char buf3[40];
				sprintf(buf3, "%f", z);

				message_ += "(";
				message_ += buf1;
				message_ += ",";
				message_ += buf2;
				message_ += ",";
				message_ += buf3;
				message_ += ")";
				globalHandler.setMessage(message_);
			}

			ParseError::ParseError(const char* file, int line,
					const String& expression, const String& message)
				throw()
				: GeneralException(file, line, "Parse Error", "")
			{

				message_ += message;
				message_ += " in ";
				message_ += expression;
				globalHandler.setMessage(message_);
			}

			Precondition::Precondition(const char* file, int line, const char* condition)
				throw()
				: GeneralException(file, line, "Precondition failed", "")
			{
				message_ += std::string(condition);
				globalHandler.setMessage(message_);
			}

			Postcondition::Postcondition(const char* file, int line, const char* condition)
				throw()
				: GeneralException(file, line, "Postcondition failed", "")
			{
				message_ += std::string(condition);
				globalHandler.setMessage(message_);
			}

			FileNotFound::FileNotFound(const char* file, int line, const String& filename)
				throw()
				:	GeneralException(file, line, "FileNotFound", ""),
					filename_(filename)
			{
				message_ = "the file " + filename + " could not be found";
				globalHandler.setMessage(message_);
			}

			FileNotFound::~FileNotFound()
				throw()
			{
			}

			String FileNotFound::getFilename() const
				throw()
			{
				return filename_;
			}

			InvalidFormat::InvalidFormat(const char* file, int line, const String& s)
				throw()
				:	GeneralException(file, line, "InvalidFormat", ""),
					format_(s)
			{
				message_ = "problem converting '";
				message_.append(s + "' to a number.");

				globalHandler.setMessage(message_);
			}

			InvalidFormat::~InvalidFormat()
				throw()
			{
			}

			InvalidOption::InvalidOption(const char* file, int line, String option)
				throw()
				: GeneralException(file, line, "Invalid option: ", option)
			{
			}

			TooManyErrors::TooManyErrors(const char* file, int line)
				throw()
				: GeneralException(file, line, "Too many errors", "")
			{
			}

			DEF_EXCEPTION(DivisionByZero, "a division by zero was requested")

			DEF_EXCEPTION(InvalidRange, "the range of the operation was invalid")

			DEF_EXCEPTION(OutOfRange, "the argument was not in range")

			DEF_EXCEPTION(NullPointer, "a null pointer was specified")

			DEF_EXCEPTION(InvalidIterator, "the iterator is invalid - probably it is not bound to a container")

			DEF_EXCEPTION(IncompatibleIterators, "the iterator could not be assigned because it is bound to a different container")

			DEF_EXCEPTION(NotImplemented, "this method has not been implemented yet. Feel free to complain about it!")

			DEF_EXCEPTION(IllegalSelfOperation, "cannot perform operation on the same object")

			DEF_EXCEPTION(IllegalTreeOperation, "an illegal tree operation was requested")

			DEF_EXCEPTION(BufferOverflow, "the maximum buffersize has been reached")

			DEF_EXCEPTION(OutOfGrid, "a point was outside a grid")

			GlobalExceptionHandler::GlobalExceptionHandler()
				throw()
			{
				std::set_terminate(terminate);
				std::set_unexpected(terminate);
				std::set_new_handler(newHandler);
			}

			void GlobalExceptionHandler::newHandler()
				throw(Exception::OutOfMemory)
			{
				throw Exception::OutOfMemory(__FILE__, __LINE__);
			}

			void GlobalExceptionHandler::terminate()
				throw()
			{
				// add cerr to the log stream
				// and write all available information on
				// the exception to the log stream (potentially with an assigned file!)
				// and cerr

				Log.insert(std::cerr);
				Log.error() << endl;
				Log.error() << "---------------------------------------------------" << endl;
				Log.error() << "FATAL: uncaught exception!" << endl;
				Log.error() << "---------------------------------------------------" << endl;
				if ((line_ != -1) && (name_ != "unknown"))
				{
					Log.error() << "last entry in the exception handler: " << endl;
					Log.error() << "exception of type " << name_.c_str() << " occured in line "
											<< line_ << " of " << file_.c_str() << endl;
					Log.error() << "error message: " << message_.c_str() << endl;
				}
				Log.error() << "---------------------------------------------------" << endl;

				// if the environment variable declared in BALL_CORE_DUMP_ENVNAME
				// is set, provoke a core dump (this is helpful to get s stack traceback)
				if (getenv(BALL_CORE_DUMP_ENVNAME) != 0)
				{
					#ifdef BALL_HAS_KILL
						Log.error() << "dumping core file.... (to avoid this, unset " << BALL_CORE_DUMP_ENVNAME
									<< " in your environment)" << endl;
						// provoke a core dump
						kill(getpid(), SIGSEGV);
					#endif
				}

				// otherwise exit cleanly
				exit(1);
			}

			void GlobalExceptionHandler::set
				(const String& file, int line,
				 const String& name, const String& message)
				throw()
			{
				name_ = name;
				line_ = line;
				message_ = message;
				file_ = file;
			}

			void GlobalExceptionHandler::setName(const String& name)
				throw()
			{
				name_ = name;
			}

			void GlobalExceptionHandler::setMessage(const String& message)
				throw()
			{
				message_ = message;
			}

			void GlobalExceptionHandler::setFile(const String& file)
				throw()
			{
				file_ = file;
			}

			void GlobalExceptionHandler::setLine(int line)
				throw()
			{
				line_ = line;
			}

			std::string	GlobalExceptionHandler::name_			= "unknown exception";
			int					GlobalExceptionHandler::line_			= -1;
			std::string	GlobalExceptionHandler::message_	= " - ";
			std::string	GlobalExceptionHandler::file_			= "unknown";

			// create a global instance of the exception handler
			GlobalExceptionHandler globalHandler;

	} // namespace Exception

	std::ostream& operator << (std::ostream& os, const Exception::GeneralException& e)
	{
		os << e.getName() << " @ " << e.getFile() << ":" << e.getLine() << ": " << e.getMessage();

		return os;
	}

} // namespace BALL
<|endoftext|>


<commit_before>/*
 * Copyright 2007-2022 CM4all GmbH
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "RedirectHttps.hxx"
#include "net/HostParser.hxx"
#include "util/StringView.hxx"
#include "AllocatorPtr.hxx"

#include <stdio.h>

const char *
MakeHttpsRedirect(AllocatorPtr alloc, const char *_host, uint16_t port,
		  const char *uri) noexcept
{
	char port_buffer[16];
	size_t port_length = 0;
	if (port != 0 && port != 443)
		port_length = sprintf(port_buffer, ":%u", port);

	auto eh = ExtractHost(_host);
	auto host = eh.host.data() != nullptr
		? eh.host
		: _host;

	static constexpr char a = '[';
	static constexpr char b = ']';
	const size_t is_ipv6 =
		std::find(eh.host.begin(), eh.host.end(), ':') != eh.host.end();
	const size_t need_brackets = is_ipv6 && port_length > 0;

	return alloc.Concat("https://",
			    StringView(&a, need_brackets),
			    host,
			    StringView(&b, need_brackets),
			    StringView(port_buffer, port_length),
			    uri);
}
<commit_msg>uri/RedirectHttps: use std::string_view<commit_after>/*
 * Copyright 2007-2022 CM4all GmbH
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "RedirectHttps.hxx"
#include "net/HostParser.hxx"
#include "AllocatorPtr.hxx"

#include <stdio.h>

const char *
MakeHttpsRedirect(AllocatorPtr alloc, const char *_host, uint16_t port,
		  const char *uri) noexcept
{
	char port_buffer[16];
	size_t port_length = 0;
	if (port != 0 && port != 443)
		port_length = sprintf(port_buffer, ":%u", port);

	auto eh = ExtractHost(_host);
	auto host = eh.host.data() != nullptr
		? eh.host
		: _host;

	static constexpr char a = '[';
	static constexpr char b = ']';
	const size_t is_ipv6 =
		std::find(eh.host.begin(), eh.host.end(), ':') != eh.host.end();
	const size_t need_brackets = is_ipv6 && port_length > 0;

	return alloc.Concat("https://",
			    std::string_view{&a, need_brackets},
			    host,
			    std::string_view{&b, need_brackets},
			    std::string_view{port_buffer, port_length},
			    uri);
}
<|endoftext|>


<commit_before>/*
 * Copyright 2011-2016 Blender Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "util_windows.h"

#ifdef _WIN32

CCL_NAMESPACE_BEGIN

#include <VersionHelpers.h>

#if _WIN32_WINNT < 0x0601
tGetActiveProcessorGroupCount *GetActiveProcessorGroupCount;
tGetActiveProcessorCount *GetActiveProcessorCount;
tSetThreadGroupAffinity *SetThreadGroupAffinity;
#endif

static WORD GetActiveProcessorGroupCount_stub()
{
	return 1;
}

static DWORD GetActiveProcessorCount_stub(WORD /*GroupNumber*/)
{
	SYSTEM_INFO info;
	GetSystemInfo(&info);
	return info.dwNumberOfProcessors;
}

static BOOL SetThreadGroupAffinity_stub(
        HANDLE /*hThread*/,
        const GROUP_AFFINITY  * /*GroupAffinity*/,
        PGROUP_AFFINITY /*PreviousGroupAffinity*/)
{
	return TRUE;
}

static bool supports_numa()
{
	return IsWindows7OrGreater();
}

void util_windows_init_numa_groups()
{
	static bool initialized = false;
	if(initialized) {
		return;
	}
	initialized = true;
#if _WIN32_WINNT < 0x0601
	if(!supports_numa()) {
		/* Use stubs on platforms which doesn't have rean NUMA/Groups. */
		GetActiveProcessorGroupCount = GetActiveProcessorGroupCount_stub;
		GetActiveProcessorCount = GetActiveProcessorCount_stub;
		SetThreadGroupAffinity = SetThreadGroupAffinity_stub;
		return;
	}
	HMODULE kernel = GetModuleHandleA("kernel32.dll");
#  define READ_SYMBOL(sym) sym = (t##sym*)GetProcAddress(kernel, #sym)
	READ_SYMBOL(GetActiveProcessorGroupCount);
	READ_SYMBOL(GetActiveProcessorCount);
	READ_SYMBOL(SetThreadGroupAffinity);
#  undef READ_SUMBOL
#endif
}

CCL_NAMESPACE_END

#endif  /* _WIN32 */
<commit_msg>Fix compilation error on 32 bit Windows<commit_after>/*
 * Copyright 2011-2016 Blender Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "util_windows.h"

#ifdef _WIN32

CCL_NAMESPACE_BEGIN

#ifdef _M_X64
#  include <VersionHelpers.h>
#endif

#if _WIN32_WINNT < 0x0601
tGetActiveProcessorGroupCount *GetActiveProcessorGroupCount;
tGetActiveProcessorCount *GetActiveProcessorCount;
tSetThreadGroupAffinity *SetThreadGroupAffinity;
#endif

static WORD GetActiveProcessorGroupCount_stub()
{
	return 1;
}

static DWORD GetActiveProcessorCount_stub(WORD /*GroupNumber*/)
{
	SYSTEM_INFO info;
	GetSystemInfo(&info);
	return info.dwNumberOfProcessors;
}

static BOOL SetThreadGroupAffinity_stub(
        HANDLE /*hThread*/,
        const GROUP_AFFINITY  * /*GroupAffinity*/,
        PGROUP_AFFINITY /*PreviousGroupAffinity*/)
{
	return TRUE;
}

static bool supports_numa()
{
#ifndef _M_X64
	return false;
#else
	return IsWindows7OrGreater();
#endif
}

void util_windows_init_numa_groups()
{
	static bool initialized = false;
	if(initialized) {
		return;
	}
	initialized = true;
#if _WIN32_WINNT < 0x0601
	if(!supports_numa()) {
		/* Use stubs on platforms which doesn't have rean NUMA/Groups. */
		GetActiveProcessorGroupCount = GetActiveProcessorGroupCount_stub;
		GetActiveProcessorCount = GetActiveProcessorCount_stub;
		SetThreadGroupAffinity = SetThreadGroupAffinity_stub;
		return;
	}
	HMODULE kernel = GetModuleHandleA("kernel32.dll");
#  define READ_SYMBOL(sym) sym = (t##sym*)GetProcAddress(kernel, #sym)
	READ_SYMBOL(GetActiveProcessorGroupCount);
	READ_SYMBOL(GetActiveProcessorCount);
	READ_SYMBOL(SetThreadGroupAffinity);
#  undef READ_SUMBOL
#endif
}

CCL_NAMESPACE_END

#endif  /* _WIN32 */
<|endoftext|>


<commit_before>//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

// ==++==
//

//
//

//
// ==--==

#include "stdafx.h"

#include "mscoree.h"
#include "clrinternal.h"
#include "hostimpl.h"
#include "predeftlsslot.h"
#include "unsafe.h"

// to avoid to include clrhost.h in this file
#ifdef FAILPOINTS_ENABLED
extern int RFS_HashStack();
#endif

static DWORD TlsIndex = TLS_OUT_OF_INDEXES;
static PTLS_CALLBACK_FUNCTION Callbacks[MAX_PREDEFINED_TLS_SLOT];

#ifdef SELF_NO_HOST
HANDLE (*g_fnGetExecutableHeapHandle)();
#endif

extern LPVOID (*__ClrFlsGetBlock)();

//
// FLS getter to avoid unnecessary indirection via execution engine.
//
VOID * ClrFlsGetBlockDirect()
{
    return UnsafeTlsGetValue(TlsIndex);
}

//
// utility functions for tls functionality
//
static void **CheckThreadState(DWORD slot, BOOL force = TRUE)
{
    // Treat as a runtime assertion, since the invariant spans many DLLs.
    _ASSERTE(slot < MAX_PREDEFINED_TLS_SLOT);

    // Ensure we have a TLS Index
    if (TlsIndex == TLS_OUT_OF_INDEXES)
    {
        DWORD tmp = UnsafeTlsAlloc();

        if (InterlockedCompareExchange((LONG*)&TlsIndex, tmp, TLS_OUT_OF_INDEXES) != (LONG) TLS_OUT_OF_INDEXES)
        {
            // We lost the race with another thread.
            UnsafeTlsFree(tmp);
        }

        // Switch to faster TLS getter now that the TLS slot is initialized
        __ClrFlsGetBlock = ClrFlsGetBlockDirect;
    }

    _ASSERTE(TlsIndex != TLS_OUT_OF_INDEXES);

    void **pTlsData = (void **)TlsGetValue(TlsIndex);

    if (pTlsData == 0 && force) {

        // !!! Contract uses our TLS support.  Contract may be used before our host support is set up.
        // !!! To better support contract, we call into OS for memory allocation.
        pTlsData = (void**) ::HeapAlloc(GetProcessHeap(),0,MAX_PREDEFINED_TLS_SLOT*sizeof(void*));

        if (pTlsData == NULL)
        {
            // workaround! We don't want exceptions being thrown during ClrInitDebugState. Just return NULL out of TlsSetValue.
            // ClrInitDebugState will do a confirming FlsGet to see if the value stuck.

            // If this is for the stack probe, and we failed to allocate memory for it, we won't
            // put in a guard page.
            if (slot == TlsIdx_ClrDebugState || slot == TlsIdx_StackProbe)
            {
                return NULL;
            }
            RaiseException(STATUS_NO_MEMORY, 0, 0, NULL);
        }
        for (int i=0; i<MAX_PREDEFINED_TLS_SLOT; i++)
            pTlsData[i] = 0;
        UnsafeTlsSetValue(TlsIndex, pTlsData);
    }

    return pTlsData;
} // CheckThreadState

// This function should only be called during process detatch for
// mscoree.dll.
VOID STDMETHODCALLTYPE TLS_FreeMasterSlotIndex()
{
    if (TlsIndex != TLS_OUT_OF_INDEXES)
        if (UnsafeTlsFree(TlsIndex))
            TlsIndex = TLS_OUT_OF_INDEXES;
} // TLS_FreeMasterSlotIndex

HRESULT STDMETHODCALLTYPE UtilExecutionEngine::QueryInterface(REFIID id, void **pInterface)
{
    if (!pInterface)
        return E_POINTER;

    *pInterface = NULL;

    if (id == IID_IExecutionEngine)
        *pInterface = (IExecutionEngine *)this;
    else if (id == IID_IEEMemoryManager)
        *pInterface = (IEEMemoryManager *)this;
    else if (id == IID_IUnknown)
        *pInterface = (IUnknown *)(IExecutionEngine *)this;
    else
        return E_NOINTERFACE;

    AddRef();
    return S_OK;
} // UtilExecutionEngine::QueryInterface

//
// lifetime of this object is that of the app it lives in so no point in AddRef/Release
//
ULONG STDMETHODCALLTYPE UtilExecutionEngine::AddRef()
{
    return 1;
}

ULONG STDMETHODCALLTYPE UtilExecutionEngine::Release()
{
    return 1;
}

VOID  STDMETHODCALLTYPE UtilExecutionEngine::TLS_AssociateCallback(DWORD slot, PTLS_CALLBACK_FUNCTION callback)
{
    CheckThreadState(slot);

    // They can toggle between a callback and no callback.  But anything else looks like
    // confusion on their part.
    //
    // (TlsIdx_ClrDebugState associates its callback from utilcode.lib - which can be replicated. But
    // all the callbacks are equally good.)
    _ASSERTE(slot == TlsIdx_ClrDebugState || Callbacks[slot] == 0 || Callbacks[slot] == callback || callback == 0);
    Callbacks[slot] = callback;
}

LPVOID* STDMETHODCALLTYPE UtilExecutionEngine::TLS_GetDataBlock()
{
    if (TlsIndex == TLS_OUT_OF_INDEXES)
        return NULL;

    return (LPVOID *)UnsafeTlsGetValue(TlsIndex);
}

LPVOID STDMETHODCALLTYPE UtilExecutionEngine::TLS_GetValue(DWORD slot)
{
    void **pTlsData = CheckThreadState(slot, FALSE);
    if (pTlsData)
        return pTlsData[slot];
    else
        return NULL;
}

BOOL STDMETHODCALLTYPE UtilExecutionEngine::TLS_CheckValue(DWORD slot, LPVOID * pValue)
{
    void **pTlsData = CheckThreadState(slot, FALSE);
    if (pTlsData)
    {
        *pValue = pTlsData[slot];
        return TRUE;
    }
    return FALSE;
}

VOID STDMETHODCALLTYPE UtilExecutionEngine::TLS_SetValue(DWORD slot, LPVOID pData)
{
    void **pTlsData = CheckThreadState(slot);
    if (pTlsData)  // Yes, CheckThreadState(slot, TRUE) can return NULL now.
    {
        pTlsData[slot] = pData;
    }
}

VOID STDMETHODCALLTYPE UtilExecutionEngine::TLS_ThreadDetaching()
{
    void **pTlsData = CheckThreadState(0, FALSE);
    if (pTlsData)
    {
        for (int i=0; i<MAX_PREDEFINED_TLS_SLOT; i++)
        {
            // If we have some data and a callback, issue it.
            if (Callbacks[i] != 0 && pTlsData[i] != 0)
                (*Callbacks[i])(pTlsData[i]);
        }
        ::HeapFree (GetProcessHeap(),0,pTlsData);

    }
}

CRITSEC_COOKIE STDMETHODCALLTYPE UtilExecutionEngine::CreateLock(LPCSTR szTag, LPCSTR level, CrstFlags flags)
{
    CRITICAL_SECTION *cs = (CRITICAL_SECTION*)malloc(sizeof(CRITICAL_SECTION));
    UnsafeInitializeCriticalSection(cs);
    return (CRITSEC_COOKIE)cs;
}

void STDMETHODCALLTYPE UtilExecutionEngine::DestroyLock(CRITSEC_COOKIE lock)
{
    _ASSERTE(lock);
    UnsafeDeleteCriticalSection((CRITICAL_SECTION*)lock);
    free(lock);
}

void STDMETHODCALLTYPE UtilExecutionEngine::AcquireLock(CRITSEC_COOKIE lock)
{
    _ASSERTE(lock);
    UnsafeEnterCriticalSection((CRITICAL_SECTION*)lock);
}

void STDMETHODCALLTYPE UtilExecutionEngine::ReleaseLock(CRITSEC_COOKIE lock)
{
    _ASSERTE(lock);
    UnsafeLeaveCriticalSection((CRITICAL_SECTION*)lock);
}

EVENT_COOKIE STDMETHODCALLTYPE UtilExecutionEngine::CreateAutoEvent(BOOL bInitialState)
{
    HANDLE handle = UnsafeCreateEvent(NULL, FALSE, bInitialState, NULL);
    _ASSERTE(handle);
    return (EVENT_COOKIE)handle;
}

EVENT_COOKIE STDMETHODCALLTYPE UtilExecutionEngine::CreateManualEvent(BOOL bInitialState)
{
    HANDLE handle = UnsafeCreateEvent(NULL, TRUE, bInitialState, NULL);
    _ASSERTE(handle);
    return (EVENT_COOKIE)handle;
}

void STDMETHODCALLTYPE UtilExecutionEngine::CloseEvent(EVENT_COOKIE event)
{
    _ASSERTE(event);
    CloseHandle((HANDLE)event);
}

BOOL STDMETHODCALLTYPE UtilExecutionEngine::ClrSetEvent(EVENT_COOKIE event)
{
    _ASSERTE(event);
    return UnsafeSetEvent((HANDLE)event);
}

BOOL STDMETHODCALLTYPE UtilExecutionEngine::ClrResetEvent(EVENT_COOKIE event)
{
    _ASSERTE(event);
    return UnsafeResetEvent((HANDLE)event);
}

DWORD STDMETHODCALLTYPE UtilExecutionEngine::WaitForEvent(EVENT_COOKIE event, DWORD dwMilliseconds, BOOL bAlertable)
{
    _ASSERTE(event);
    return WaitForSingleObjectEx((HANDLE)event, dwMilliseconds, bAlertable);
}

DWORD STDMETHODCALLTYPE UtilExecutionEngine::WaitForSingleObject(HANDLE handle, DWORD dwMilliseconds)
{
    _ASSERTE(handle);
    return WaitForSingleObject(handle, dwMilliseconds);
}

SEMAPHORE_COOKIE STDMETHODCALLTYPE UtilExecutionEngine::ClrCreateSemaphore(DWORD dwInitial, DWORD dwMax)
{
    HANDLE handle = UnsafeCreateSemaphore(NULL, (LONG)dwInitial, (LONG)dwMax, NULL);
    _ASSERTE(handle);
    return (SEMAPHORE_COOKIE)handle;
}

void STDMETHODCALLTYPE UtilExecutionEngine::ClrCloseSemaphore(SEMAPHORE_COOKIE semaphore)
{
    _ASSERTE(semaphore);
    CloseHandle((HANDLE)semaphore);
}

DWORD STDMETHODCALLTYPE UtilExecutionEngine::ClrWaitForSemaphore(SEMAPHORE_COOKIE semaphore, DWORD dwMilliseconds, BOOL bAlertable)
{
    _ASSERTE(semaphore);
    return WaitForSingleObjectEx((HANDLE)semaphore, dwMilliseconds, bAlertable);
}

BOOL STDMETHODCALLTYPE UtilExecutionEngine::ClrReleaseSemaphore(SEMAPHORE_COOKIE semaphore, LONG lReleaseCount, LONG *lpPreviousCount)
{
    _ASSERTE(semaphore);
    return UnsafeReleaseSemaphore((HANDLE)semaphore, lReleaseCount, lpPreviousCount);
}

MUTEX_COOKIE STDMETHODCALLTYPE UtilExecutionEngine::ClrCreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes,
                                                                BOOL bInitialOwner,
                                                                LPCTSTR lpName)
{
    return (MUTEX_COOKIE)WszCreateMutex(lpMutexAttributes,bInitialOwner,lpName);
}

void STDMETHODCALLTYPE UtilExecutionEngine::ClrCloseMutex(MUTEX_COOKIE mutex)
{
    _ASSERTE(mutex);
    CloseHandle((HANDLE)mutex);
}

BOOL STDMETHODCALLTYPE UtilExecutionEngine::ClrReleaseMutex(MUTEX_COOKIE mutex)
{
    _ASSERTE(mutex);
    return ReleaseMutex((HANDLE)mutex);
}

DWORD STDMETHODCALLTYPE UtilExecutionEngine::ClrWaitForMutex(MUTEX_COOKIE mutex,
                                                          DWORD dwMilliseconds,
                                                          BOOL bAlertable)
{
    _ASSERTE(mutex);
    return WaitForSingleObjectEx ((HANDLE)mutex, dwMilliseconds, bAlertable);
}

DWORD STDMETHODCALLTYPE UtilExecutionEngine::ClrSleepEx(DWORD dwMilliseconds, BOOL bAlertable)
{
    return SleepEx (dwMilliseconds, bAlertable);
}

BOOL STDMETHODCALLTYPE UtilExecutionEngine::ClrAllocationDisallowed()
{
    return FALSE;
}

LPVOID STDMETHODCALLTYPE UtilExecutionEngine::ClrVirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect)
{
#ifdef FAILPOINTS_ENABLED
        if (RFS_HashStack ())
            return NULL;
#endif
    return VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect);
}

BOOL STDMETHODCALLTYPE UtilExecutionEngine::ClrVirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType)
{
    return VirtualFree(lpAddress, dwSize, dwFreeType);
}

SIZE_T STDMETHODCALLTYPE UtilExecutionEngine::ClrVirtualQuery(LPCVOID lpAddress, PMEMORY_BASIC_INFORMATION lpBuffer, SIZE_T dwLength)
{
    return VirtualQuery(lpAddress, lpBuffer, dwLength);
}

BOOL STDMETHODCALLTYPE UtilExecutionEngine::ClrVirtualProtect(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect)
{
    return VirtualProtect(lpAddress, dwSize, flNewProtect, lpflOldProtect);
}

HANDLE STDMETHODCALLTYPE UtilExecutionEngine::ClrGetProcessHeap()
{
    return GetProcessHeap();
}

HANDLE STDMETHODCALLTYPE UtilExecutionEngine::ClrGetProcessExecutableHeap()
{
#ifndef CROSSGEN_COMPILE
    _ASSERTE(g_fnGetExecutableHeapHandle);
    return (g_fnGetExecutableHeapHandle != NULL) ? g_fnGetExecutableHeapHandle() : NULL;
#else
    return GetProcessHeap();
#endif
}

HANDLE STDMETHODCALLTYPE UtilExecutionEngine::ClrHeapCreate(DWORD flOptions, SIZE_T dwInitialSize, SIZE_T dwMaximumSize)
{
#ifdef FEATURE_PAL
    return NULL;
#else
    return HeapCreate(flOptions, dwInitialSize, dwMaximumSize);
#endif
}

BOOL STDMETHODCALLTYPE UtilExecutionEngine::ClrHeapDestroy(HANDLE hHeap)
{
#ifdef FEATURE_PAL
    return FALSE;
#else
    return HeapDestroy(hHeap);
#endif
}

LPVOID STDMETHODCALLTYPE UtilExecutionEngine::ClrHeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes)
{
#ifdef FAILPOINTS_ENABLED
        if (RFS_HashStack ())
            return NULL;
#endif
    return HeapAlloc(hHeap, dwFlags, dwBytes);
}

BOOL STDMETHODCALLTYPE UtilExecutionEngine::ClrHeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem)
{
    return HeapFree(hHeap, dwFlags, lpMem);
}

BOOL STDMETHODCALLTYPE UtilExecutionEngine::ClrHeapValidate(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem)
{
#ifdef FEATURE_PAL
    return FALSE;
#else
    return HeapValidate(hHeap, dwFlags, lpMem);
#endif
}

//------------------------------------------------------------------------------
// Helper function to get an exception from outside the exception.  In
//  the CLR, it may be from the Thread object.  Non-CLR users have no thread object,
//  and it will do nothing.

void UtilExecutionEngine::GetLastThrownObjectExceptionFromThread(void **ppvException)
{
    // Declare class so we can declare Exception**
    class Exception;

    // Cast to our real type.
    Exception **ppException = reinterpret_cast<Exception**>(ppvException);

    *ppException = NULL;
} // UtilExecutionEngine::GetLastThrownObjectExceptionFromThread

<commit_msg>Fix infinite recursion in hostimpl.cpp<commit_after>//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

// ==++==
//

//
//

//
// ==--==

#include "stdafx.h"

#include "mscoree.h"
#include "clrinternal.h"
#include "hostimpl.h"
#include "predeftlsslot.h"
#include "unsafe.h"

// to avoid to include clrhost.h in this file
#ifdef FAILPOINTS_ENABLED
extern int RFS_HashStack();
#endif

static DWORD TlsIndex = TLS_OUT_OF_INDEXES;
static PTLS_CALLBACK_FUNCTION Callbacks[MAX_PREDEFINED_TLS_SLOT];

#ifdef SELF_NO_HOST
HANDLE (*g_fnGetExecutableHeapHandle)();
#endif

extern LPVOID (*__ClrFlsGetBlock)();

//
// FLS getter to avoid unnecessary indirection via execution engine.
//
VOID * ClrFlsGetBlockDirect()
{
    return UnsafeTlsGetValue(TlsIndex);
}

//
// utility functions for tls functionality
//
static void **CheckThreadState(DWORD slot, BOOL force = TRUE)
{
    // Treat as a runtime assertion, since the invariant spans many DLLs.
    _ASSERTE(slot < MAX_PREDEFINED_TLS_SLOT);

    // Ensure we have a TLS Index
    if (TlsIndex == TLS_OUT_OF_INDEXES)
    {
        DWORD tmp = UnsafeTlsAlloc();

        if (InterlockedCompareExchange((LONG*)&TlsIndex, tmp, TLS_OUT_OF_INDEXES) != (LONG) TLS_OUT_OF_INDEXES)
        {
            // We lost the race with another thread.
            UnsafeTlsFree(tmp);
        }

        // Switch to faster TLS getter now that the TLS slot is initialized
        __ClrFlsGetBlock = ClrFlsGetBlockDirect;
    }

    _ASSERTE(TlsIndex != TLS_OUT_OF_INDEXES);

    void **pTlsData = (void **)TlsGetValue(TlsIndex);

    if (pTlsData == 0 && force) {

        // !!! Contract uses our TLS support.  Contract may be used before our host support is set up.
        // !!! To better support contract, we call into OS for memory allocation.
        pTlsData = (void**) ::HeapAlloc(GetProcessHeap(),0,MAX_PREDEFINED_TLS_SLOT*sizeof(void*));

        if (pTlsData == NULL)
        {
            // workaround! We don't want exceptions being thrown during ClrInitDebugState. Just return NULL out of TlsSetValue.
            // ClrInitDebugState will do a confirming FlsGet to see if the value stuck.

            // If this is for the stack probe, and we failed to allocate memory for it, we won't
            // put in a guard page.
            if (slot == TlsIdx_ClrDebugState || slot == TlsIdx_StackProbe)
            {
                return NULL;
            }
            RaiseException(STATUS_NO_MEMORY, 0, 0, NULL);
        }
        for (int i=0; i<MAX_PREDEFINED_TLS_SLOT; i++)
            pTlsData[i] = 0;
        UnsafeTlsSetValue(TlsIndex, pTlsData);
    }

    return pTlsData;
} // CheckThreadState

// This function should only be called during process detatch for
// mscoree.dll.
VOID STDMETHODCALLTYPE TLS_FreeMasterSlotIndex()
{
    if (TlsIndex != TLS_OUT_OF_INDEXES)
        if (UnsafeTlsFree(TlsIndex))
            TlsIndex = TLS_OUT_OF_INDEXES;
} // TLS_FreeMasterSlotIndex

HRESULT STDMETHODCALLTYPE UtilExecutionEngine::QueryInterface(REFIID id, void **pInterface)
{
    if (!pInterface)
        return E_POINTER;

    *pInterface = NULL;

    if (id == IID_IExecutionEngine)
        *pInterface = (IExecutionEngine *)this;
    else if (id == IID_IEEMemoryManager)
        *pInterface = (IEEMemoryManager *)this;
    else if (id == IID_IUnknown)
        *pInterface = (IUnknown *)(IExecutionEngine *)this;
    else
        return E_NOINTERFACE;

    AddRef();
    return S_OK;
} // UtilExecutionEngine::QueryInterface

//
// lifetime of this object is that of the app it lives in so no point in AddRef/Release
//
ULONG STDMETHODCALLTYPE UtilExecutionEngine::AddRef()
{
    return 1;
}

ULONG STDMETHODCALLTYPE UtilExecutionEngine::Release()
{
    return 1;
}

VOID  STDMETHODCALLTYPE UtilExecutionEngine::TLS_AssociateCallback(DWORD slot, PTLS_CALLBACK_FUNCTION callback)
{
    CheckThreadState(slot);

    // They can toggle between a callback and no callback.  But anything else looks like
    // confusion on their part.
    //
    // (TlsIdx_ClrDebugState associates its callback from utilcode.lib - which can be replicated. But
    // all the callbacks are equally good.)
    _ASSERTE(slot == TlsIdx_ClrDebugState || Callbacks[slot] == 0 || Callbacks[slot] == callback || callback == 0);
    Callbacks[slot] = callback;
}

LPVOID* STDMETHODCALLTYPE UtilExecutionEngine::TLS_GetDataBlock()
{
    if (TlsIndex == TLS_OUT_OF_INDEXES)
        return NULL;

    return (LPVOID *)UnsafeTlsGetValue(TlsIndex);
}

LPVOID STDMETHODCALLTYPE UtilExecutionEngine::TLS_GetValue(DWORD slot)
{
    void **pTlsData = CheckThreadState(slot, FALSE);
    if (pTlsData)
        return pTlsData[slot];
    else
        return NULL;
}

BOOL STDMETHODCALLTYPE UtilExecutionEngine::TLS_CheckValue(DWORD slot, LPVOID * pValue)
{
    void **pTlsData = CheckThreadState(slot, FALSE);
    if (pTlsData)
    {
        *pValue = pTlsData[slot];
        return TRUE;
    }
    return FALSE;
}

VOID STDMETHODCALLTYPE UtilExecutionEngine::TLS_SetValue(DWORD slot, LPVOID pData)
{
    void **pTlsData = CheckThreadState(slot);
    if (pTlsData)  // Yes, CheckThreadState(slot, TRUE) can return NULL now.
    {
        pTlsData[slot] = pData;
    }
}

VOID STDMETHODCALLTYPE UtilExecutionEngine::TLS_ThreadDetaching()
{
    void **pTlsData = CheckThreadState(0, FALSE);
    if (pTlsData)
    {
        for (int i=0; i<MAX_PREDEFINED_TLS_SLOT; i++)
        {
            // If we have some data and a callback, issue it.
            if (Callbacks[i] != 0 && pTlsData[i] != 0)
                (*Callbacks[i])(pTlsData[i]);
        }
        ::HeapFree (GetProcessHeap(),0,pTlsData);

    }
}

CRITSEC_COOKIE STDMETHODCALLTYPE UtilExecutionEngine::CreateLock(LPCSTR szTag, LPCSTR level, CrstFlags flags)
{
    CRITICAL_SECTION *cs = (CRITICAL_SECTION*)malloc(sizeof(CRITICAL_SECTION));
    UnsafeInitializeCriticalSection(cs);
    return (CRITSEC_COOKIE)cs;
}

void STDMETHODCALLTYPE UtilExecutionEngine::DestroyLock(CRITSEC_COOKIE lock)
{
    _ASSERTE(lock);
    UnsafeDeleteCriticalSection((CRITICAL_SECTION*)lock);
    free(lock);
}

void STDMETHODCALLTYPE UtilExecutionEngine::AcquireLock(CRITSEC_COOKIE lock)
{
    _ASSERTE(lock);
    UnsafeEnterCriticalSection((CRITICAL_SECTION*)lock);
}

void STDMETHODCALLTYPE UtilExecutionEngine::ReleaseLock(CRITSEC_COOKIE lock)
{
    _ASSERTE(lock);
    UnsafeLeaveCriticalSection((CRITICAL_SECTION*)lock);
}

EVENT_COOKIE STDMETHODCALLTYPE UtilExecutionEngine::CreateAutoEvent(BOOL bInitialState)
{
    HANDLE handle = UnsafeCreateEvent(NULL, FALSE, bInitialState, NULL);
    _ASSERTE(handle);
    return (EVENT_COOKIE)handle;
}

EVENT_COOKIE STDMETHODCALLTYPE UtilExecutionEngine::CreateManualEvent(BOOL bInitialState)
{
    HANDLE handle = UnsafeCreateEvent(NULL, TRUE, bInitialState, NULL);
    _ASSERTE(handle);
    return (EVENT_COOKIE)handle;
}

void STDMETHODCALLTYPE UtilExecutionEngine::CloseEvent(EVENT_COOKIE event)
{
    _ASSERTE(event);
    CloseHandle((HANDLE)event);
}

BOOL STDMETHODCALLTYPE UtilExecutionEngine::ClrSetEvent(EVENT_COOKIE event)
{
    _ASSERTE(event);
    return UnsafeSetEvent((HANDLE)event);
}

BOOL STDMETHODCALLTYPE UtilExecutionEngine::ClrResetEvent(EVENT_COOKIE event)
{
    _ASSERTE(event);
    return UnsafeResetEvent((HANDLE)event);
}

DWORD STDMETHODCALLTYPE UtilExecutionEngine::WaitForEvent(EVENT_COOKIE event, DWORD dwMilliseconds, BOOL bAlertable)
{
    _ASSERTE(event);
    return WaitForSingleObjectEx((HANDLE)event, dwMilliseconds, bAlertable);
}

DWORD STDMETHODCALLTYPE UtilExecutionEngine::WaitForSingleObject(HANDLE handle, DWORD dwMilliseconds)
{
    _ASSERTE(handle);
    return WaitForSingleObjectEx(handle, dwMilliseconds, FALSE);
}

SEMAPHORE_COOKIE STDMETHODCALLTYPE UtilExecutionEngine::ClrCreateSemaphore(DWORD dwInitial, DWORD dwMax)
{
    HANDLE handle = UnsafeCreateSemaphore(NULL, (LONG)dwInitial, (LONG)dwMax, NULL);
    _ASSERTE(handle);
    return (SEMAPHORE_COOKIE)handle;
}

void STDMETHODCALLTYPE UtilExecutionEngine::ClrCloseSemaphore(SEMAPHORE_COOKIE semaphore)
{
    _ASSERTE(semaphore);
    CloseHandle((HANDLE)semaphore);
}

DWORD STDMETHODCALLTYPE UtilExecutionEngine::ClrWaitForSemaphore(SEMAPHORE_COOKIE semaphore, DWORD dwMilliseconds, BOOL bAlertable)
{
    _ASSERTE(semaphore);
    return WaitForSingleObjectEx((HANDLE)semaphore, dwMilliseconds, bAlertable);
}

BOOL STDMETHODCALLTYPE UtilExecutionEngine::ClrReleaseSemaphore(SEMAPHORE_COOKIE semaphore, LONG lReleaseCount, LONG *lpPreviousCount)
{
    _ASSERTE(semaphore);
    return UnsafeReleaseSemaphore((HANDLE)semaphore, lReleaseCount, lpPreviousCount);
}

MUTEX_COOKIE STDMETHODCALLTYPE UtilExecutionEngine::ClrCreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes,
                                                                BOOL bInitialOwner,
                                                                LPCTSTR lpName)
{
    return (MUTEX_COOKIE)WszCreateMutex(lpMutexAttributes,bInitialOwner,lpName);
}

void STDMETHODCALLTYPE UtilExecutionEngine::ClrCloseMutex(MUTEX_COOKIE mutex)
{
    _ASSERTE(mutex);
    CloseHandle((HANDLE)mutex);
}

BOOL STDMETHODCALLTYPE UtilExecutionEngine::ClrReleaseMutex(MUTEX_COOKIE mutex)
{
    _ASSERTE(mutex);
    return ReleaseMutex((HANDLE)mutex);
}

DWORD STDMETHODCALLTYPE UtilExecutionEngine::ClrWaitForMutex(MUTEX_COOKIE mutex,
                                                          DWORD dwMilliseconds,
                                                          BOOL bAlertable)
{
    _ASSERTE(mutex);
    return WaitForSingleObjectEx ((HANDLE)mutex, dwMilliseconds, bAlertable);
}

DWORD STDMETHODCALLTYPE UtilExecutionEngine::ClrSleepEx(DWORD dwMilliseconds, BOOL bAlertable)
{
    return SleepEx (dwMilliseconds, bAlertable);
}

BOOL STDMETHODCALLTYPE UtilExecutionEngine::ClrAllocationDisallowed()
{
    return FALSE;
}

LPVOID STDMETHODCALLTYPE UtilExecutionEngine::ClrVirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect)
{
#ifdef FAILPOINTS_ENABLED
        if (RFS_HashStack ())
            return NULL;
#endif
    return VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect);
}

BOOL STDMETHODCALLTYPE UtilExecutionEngine::ClrVirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType)
{
    return VirtualFree(lpAddress, dwSize, dwFreeType);
}

SIZE_T STDMETHODCALLTYPE UtilExecutionEngine::ClrVirtualQuery(LPCVOID lpAddress, PMEMORY_BASIC_INFORMATION lpBuffer, SIZE_T dwLength)
{
    return VirtualQuery(lpAddress, lpBuffer, dwLength);
}

BOOL STDMETHODCALLTYPE UtilExecutionEngine::ClrVirtualProtect(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect)
{
    return VirtualProtect(lpAddress, dwSize, flNewProtect, lpflOldProtect);
}

HANDLE STDMETHODCALLTYPE UtilExecutionEngine::ClrGetProcessHeap()
{
    return GetProcessHeap();
}

HANDLE STDMETHODCALLTYPE UtilExecutionEngine::ClrGetProcessExecutableHeap()
{
#ifndef CROSSGEN_COMPILE
    _ASSERTE(g_fnGetExecutableHeapHandle);
    return (g_fnGetExecutableHeapHandle != NULL) ? g_fnGetExecutableHeapHandle() : NULL;
#else
    return GetProcessHeap();
#endif
}

HANDLE STDMETHODCALLTYPE UtilExecutionEngine::ClrHeapCreate(DWORD flOptions, SIZE_T dwInitialSize, SIZE_T dwMaximumSize)
{
#ifdef FEATURE_PAL
    return NULL;
#else
    return HeapCreate(flOptions, dwInitialSize, dwMaximumSize);
#endif
}

BOOL STDMETHODCALLTYPE UtilExecutionEngine::ClrHeapDestroy(HANDLE hHeap)
{
#ifdef FEATURE_PAL
    return FALSE;
#else
    return HeapDestroy(hHeap);
#endif
}

LPVOID STDMETHODCALLTYPE UtilExecutionEngine::ClrHeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes)
{
#ifdef FAILPOINTS_ENABLED
        if (RFS_HashStack ())
            return NULL;
#endif
    return HeapAlloc(hHeap, dwFlags, dwBytes);
}

BOOL STDMETHODCALLTYPE UtilExecutionEngine::ClrHeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem)
{
    return HeapFree(hHeap, dwFlags, lpMem);
}

BOOL STDMETHODCALLTYPE UtilExecutionEngine::ClrHeapValidate(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem)
{
#ifdef FEATURE_PAL
    return FALSE;
#else
    return HeapValidate(hHeap, dwFlags, lpMem);
#endif
}

//------------------------------------------------------------------------------
// Helper function to get an exception from outside the exception.  In
//  the CLR, it may be from the Thread object.  Non-CLR users have no thread object,
//  and it will do nothing.

void UtilExecutionEngine::GetLastThrownObjectExceptionFromThread(void **ppvException)
{
    // Declare class so we can declare Exception**
    class Exception;

    // Cast to our real type.
    Exception **ppException = reinterpret_cast<Exception**>(ppvException);

    *ppException = NULL;
} // UtilExecutionEngine::GetLastThrownObjectExceptionFromThread

<|endoftext|>


<commit_before>#include "mapped_file.h"

#include <exception/os.h>

#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>

namespace sasm { namespace utils {

mapped_file::~mapped_file()
{
  if (_is_mapped)
    unmap();
}

void mapped_file::map()
{
  int fd;
  struct stat buf;
  char* begin;

  if ((fd = open(get_path(), O_RDONLY)) == -1)
    throw sasm::exception::os("open", get_path());

  if (fstat(fd, &buf) == -1)
    throw sasm::exception::os("fstat");

  if ((begin = (char*) mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED)
    throw sasm::exception::os("mmap");

  close(fd);

  _is_mapped = true;
  _begin = begin;
  _size = buf.st_size;
}

void mapped_file::unmap()
{
  if (munmap((void*) _begin, _size) == -1)
    throw sasm::exception::os("munmap");

  _is_mapped = false;
}

const char* mapped_file::get_path() const
{
  return _path.c_str();
}

}}
<commit_msg>Handle a little bug with empty files.<commit_after>#include "mapped_file.h"

#include <exception/elf.h>
#include <exception/os.h>

#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>

namespace sasm { namespace utils {

mapped_file::~mapped_file()
{
  if (_is_mapped)
    unmap();
}

void mapped_file::map()
{
  int fd;
  struct stat buf;
  char* begin;

  if ((fd = open(get_path(), O_RDONLY)) == -1)
    throw sasm::exception::os("open", get_path());

  if (fstat(fd, &buf) == -1)
    throw sasm::exception::os("fstat");

  if (buf.st_size == 0)
    throw sasm::exception::elf(_path.c_str(), "invalid ELF file");

  if ((begin = (char*) mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED)
    throw sasm::exception::os("mmap");

  close(fd);

  _is_mapped = true;
  _begin = begin;
  _size = buf.st_size;
}

void mapped_file::unmap()
{
  if (munmap((void*) _begin, _size) == -1)
    throw sasm::exception::os("munmap");

  _is_mapped = false;
}

const char* mapped_file::get_path() const
{
  return _path.c_str();
}

}}
<|endoftext|>


<commit_before>#include "vast/configuration.h"
#include "vast/file_system.h"
#include "vast/logger.h"
#include "vast/string.h"
#include "vast/type_info.h"
#include "vast/detail/type_manager.h"

namespace vast {

std::string configuration::banner() const
{
  std::stringstream ss;
  ss << " _   _____   __________\n"
        "| | / / _ | / __/_  __/\n"
        "| |/ / __ |_\\ \\  / /\n"
        "|___/_/ |_/___/ /_/  " << VAST_VERSION;

  return ss.str();
}

void configuration::initialize()
{
  auto& general = create_block("general options");
  general.add('c', "config", "configuration file");
  general.add('h', "help", "display this help");
  general.add('d', "directory", "VAST directory").init("vast");
  general.add('z', "advanced", "show advanced options");

  auto& log = create_block("logger options", "log");
  log.add('v', "console-verbosity", "console verbosity").init(3);
  log.add('V', "file-verbosity", "log file verbosity").init(4);
  log.add("function-names", "log function names");

  auto& advanced = create_block("advanced options");
  advanced.add('P', "profile", "enable getrusage profiling at a given interval (seconds)").single();
#ifdef VAST_USE_PERFTOOLS_CPU_PROFILER
  advanced.add("profile-cpu", "also enable Google perftools CPU profiling");
#endif
#ifdef VAST_USE_PERFTOOLS_HEAP_PROFILER
  advanced.add("profile-heap", "also enable Google perftools heap profiling");
#endif
#ifdef VAST_HAVE_BROCCOLI
  advanced.add("broccoli-messages", "enable broccoli debug messages");
  advanced.add("broccoli-calltrace", "enable broccoli function call tracing");
#endif
  advanced.visible(false);

  auto& actor = create_block("actor options");
#ifdef VAST_HAVE_EDITLINE
  actor.add('C', "console-actor", "spawn the console client actor");
#endif
  actor.add('a', "all-server", "spawn all server actors");
  actor.add('A', "archive-actor", "spawn the archive");
  actor.add('I', "ingestor-actor", "spawn the ingestor");
  actor.add('X', "index-actor", "spawn the index");
  actor.add('S', "search-actor", "spawn the search");
  actor.add('T', "tracker-actor", "spawn the ID tracker");
  actor.visible(false);

  auto& schema = create_block("schema options", "schema");
  schema.add('s', "file", "schema file").single();
  schema.add("print", "print the parsed event schema");
  schema.visible(false);

  auto& ingest = create_block("ingest options", "ingest");
  ingest.add("max-events-per-chunk", "maximum number of events per chunk").init(5000);
  ingest.add("max-segment-size", "maximum segment size in MB").init("128");
  ingest.add("batch-size", "number of events to ingest in one run").init(4000);
  ingest.add("file-names", "file(s) to ingest").multi();
  ingest.add("file-type", "file type of the file(s) to ingest").init("bro2");
#ifdef VAST_HAVE_BROCCOLI
  ingest.add("broccoli-host", "hostname/address of the broccoli source").init("127.0.0.1");
  ingest.add("broccoli-port", "port of the broccoli source").init(42000);
  ingest.add("broccoli-events", "list of events for broccoli to subscribe to").multi();
#endif
  ingest.visible(false);

  auto& receiver = create_block("receiver options", "receiver");
  receiver.add("host", "hostname/address of the receiver").init("127.0.0.1");
  receiver.add("port", "TCP port of the receiver").init(42000);
  receiver.visible(false);

  auto& archive = create_block("archive options", "archive");
  archive.add("host", "hostname/address of the archive").init("127.0.0.1");
  archive.add("port", "TCP port of the archive").init(42003);
  archive.add("max-segments", "maximum number of segments to keep in memory").init(500);
  archive.visible(false);

  auto& index = create_block("index options", "index");
  index.add("host", "hostname/address of the archive").init("127.0.0.1");
  index.add("port", "TCP port of the index").init(42004);
  index.visible(false);

  auto& tracker = create_block("ID tracker options", "tracker");
  tracker.add("host", "hostname/address of the tracker").init("127.0.0.1");
  tracker.add("port", "TCP port of the ID tracker").init(42002);
  tracker.visible(false);

  auto& search = create_block("search options", "search");
  search.add("host", "hostname/address of the archive").init("127.0.0.1");
  search.add("port", "TCP port of the search").init(42001);
  search.visible(false);

  add_dependency("schema.print", "schema.file");

#ifdef VAST_HAVE_EDITLINE
  add_conflict("console-actor", "all-server");
  add_conflict("console-actor", "tracker-actor");
  add_conflict("console-actor", "archive-actor");
  add_conflict("console-actor", "index-actor");
  add_conflict("console-actor", "ingestor-actor");
  add_conflict("console-actor", "search-actor");
#endif
}

} // namespace vast
<commit_msg>Correctly display log levels in config.<commit_after>#include "vast/configuration.h"
#include "vast/file_system.h"
#include "vast/logger.h"
#include "vast/string.h"
#include "vast/type_info.h"
#include "vast/detail/type_manager.h"

namespace vast {

std::string configuration::banner() const
{
  std::stringstream ss;
  ss << " _   _____   __________\n"
        "| | / / _ | / __/_  __/\n"
        "| |/ / __ |_\\ \\  / /\n"
        "|___/_/ |_/___/ /_/  " << VAST_VERSION;

  return ss.str();
}

void configuration::initialize()
{
  auto& general = create_block("general options");
  general.add('c', "config", "configuration file");
  general.add('h', "help", "display this help");
  general.add('d', "directory", "VAST directory").init("vast");
  general.add('z', "advanced", "show advanced options");

  auto min = 0;
  auto max = VAST_LOG_LEVEL;
  auto range = '[' + std::to_string(min) + '-' + std::to_string(max) + ']';

  auto& log = create_block("logger options", "log");
  log.add('v', "console-verbosity", "console verbosity " + range)
     .init(std::max(3, max));
  log.add('V', "file-verbosity", "log file verbosity " + range)
     .init(std::max(4, max));
  log.add("function-names", "log function names");

  auto& advanced = create_block("advanced options");
  advanced.add('P', "profile",
               "enable getrusage profiling at a given interval (seconds)")
          .single();
#ifdef VAST_USE_PERFTOOLS_CPU_PROFILER
  advanced.add("profile-cpu", "also enable Google perftools CPU profiling");
#endif
#ifdef VAST_USE_PERFTOOLS_HEAP_PROFILER
  advanced.add("profile-heap", "also enable Google perftools heap profiling");
#endif
#ifdef VAST_HAVE_BROCCOLI
  advanced.add("broccoli-messages", "enable broccoli debug messages");
  advanced.add("broccoli-calltrace", "enable broccoli function call tracing");
#endif
  advanced.visible(false);

  auto& actor = create_block("actor options");
#ifdef VAST_HAVE_EDITLINE
  actor.add('C', "console-actor", "spawn the console client actor");
#endif
  actor.add('a', "all-server", "spawn all server actors");
  actor.add('A', "archive-actor", "spawn the archive");
  actor.add('I', "ingestor-actor", "spawn the ingestor");
  actor.add('X', "index-actor", "spawn the index");
  actor.add('S', "search-actor", "spawn the search");
  actor.add('T', "tracker-actor", "spawn the ID tracker");
  actor.visible(false);

  auto& schema = create_block("schema options", "schema");
  schema.add('s', "file", "schema file").single();
  schema.add("print", "print the parsed event schema");
  schema.visible(false);

  auto& ingest = create_block("ingest options", "ingest");
  ingest.add("max-events-per-chunk", "maximum number of events per chunk")
        .init(5000);
  ingest.add("max-segment-size", "maximum segment size in MB").init(128);
  ingest.add("batch-size", "number of events to ingest in one run").init(4000);
  ingest.add("file-names", "file(s) to ingest").multi();
  ingest.add("file-type", "file type of the file(s) to ingest").init("bro2");
#ifdef VAST_HAVE_BROCCOLI
  ingest.add("broccoli-host", "hostname/address of the broccoli source")
        .init("127.0.0.1");
  ingest.add("broccoli-port", "port of the broccoli source").init(42000);
  ingest.add("broccoli-events", "list of events for broccoli to subscribe to")
        .multi();
#endif
  ingest.visible(false);

  auto& receiver = create_block("receiver options", "receiver");
  receiver.add("host", "hostname/address of the receiver").init("127.0.0.1");
  receiver.add("port", "TCP port of the receiver").init(42000);
  receiver.visible(false);

  auto& archive = create_block("archive options", "archive");
  archive.add("host", "hostname/address of the archive").init("127.0.0.1");
  archive.add("port", "TCP port of the archive").init(42003);
  archive.add("max-segments", "maximum number of segments to keep in memory")
         .init(500);
  archive.visible(false);

  auto& index = create_block("index options", "index");
  index.add("host", "hostname/address of the archive").init("127.0.0.1");
  index.add("port", "TCP port of the index").init(42004);
  index.visible(false);

  auto& tracker = create_block("ID tracker options", "tracker");
  tracker.add("host", "hostname/address of the tracker").init("127.0.0.1");
  tracker.add("port", "TCP port of the ID tracker").init(42002);
  tracker.visible(false);

  auto& search = create_block("search options", "search");
  search.add("host", "hostname/address of the archive").init("127.0.0.1");
  search.add("port", "TCP port of the search").init(42001);
  search.visible(false);

  add_dependency("schema.print", "schema.file");

#ifdef VAST_HAVE_EDITLINE
  add_conflict("console-actor", "all-server");
  add_conflict("console-actor", "tracker-actor");
  add_conflict("console-actor", "archive-actor");
  add_conflict("console-actor", "index-actor");
  add_conflict("console-actor", "ingestor-actor");
  add_conflict("console-actor", "search-actor");
#endif
}

} // namespace vast
<|endoftext|>