// Copyright (c) 2007, Google Inc.
// All rights reserved.
//
// 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.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// 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 COPYRIGHT
// OWNER 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.

#import "OnDemandServer.h"

#import "Breakpad.h"
#include "common/mac/bootstrap_compat.h"

#if DEBUG
  #define PRINT_MACH_RESULT(result_, message_) \
    printf(message_"%s (%d)\n", mach_error_string(result_), result_ );
#if defined(MAC_OS_X_VERSION_10_5) && \
    MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
  #define PRINT_BOOTSTRAP_RESULT(result_, message_) \
    printf(message_"%s (%d)\n", bootstrap_strerror(result_), result_ );
#else
  #define PRINT_BOOTSTRAP_RESULT(result_, message_) \
    PRINT_MACH_RESULT(result_, message_)
#endif
#else
  #define PRINT_MACH_RESULT(result_, message_)
  #define PRINT_BOOTSTRAP_RESULT(result_, message_)
#endif

//==============================================================================
OnDemandServer* OnDemandServer::Create(const char* server_command,
                                       const char* service_name,
                                       bool unregister_on_cleanup,
                                       kern_return_t* out_result) {
  OnDemandServer* server = new OnDemandServer();

  if (!server) return NULL;

  kern_return_t result = server->Initialize(server_command,
                                            service_name,
                                            unregister_on_cleanup);

  if (out_result) {
    *out_result = result;
  }

  if (result == KERN_SUCCESS) {
    return server;
  }

  delete server;
  return NULL;
}

//==============================================================================
kern_return_t OnDemandServer::Initialize(const char* server_command,
                                         const char* service_name,
                                         bool unregister_on_cleanup) {
  unregister_on_cleanup_ = unregister_on_cleanup;

  mach_port_t self_task = mach_task_self();

  mach_port_t bootstrap_port;
  kern_return_t kr = task_get_bootstrap_port(self_task, &bootstrap_port);
  if (kr != KERN_SUCCESS) {
    PRINT_MACH_RESULT(kr, "task_get_bootstrap_port(): ");
    return kr;
  }

  mach_port_t bootstrap_subset_port;
  kr = bootstrap_subset(bootstrap_port, self_task, &bootstrap_subset_port);
  if (kr != BOOTSTRAP_SUCCESS) {
    PRINT_BOOTSTRAP_RESULT(kr, "bootstrap_subset(): ");
    return kr;
  }

  // The inspector will be invoked with its bootstrap port set to the subset,
  // but the sender will need access to the original bootstrap port. Although
  // the original port is the subset's parent, bootstrap_parent can't be used
  // because it requires extra privileges. Stash the original bootstrap port
  // in the subset by registering it under a known name. The inspector will
  // recover this port and set it as its own bootstrap port in Inspector.mm
  // Inspector::ResetBootstrapPort.
  kr = breakpad::BootstrapRegister(
      bootstrap_subset_port,
      const_cast<char*>(BREAKPAD_BOOTSTRAP_PARENT_PORT),
      bootstrap_port);
  if (kr != BOOTSTRAP_SUCCESS) {
    PRINT_BOOTSTRAP_RESULT(kr, "bootstrap_register(): ");
    return kr;
  }

  kr = bootstrap_create_server(bootstrap_subset_port,
                               const_cast<char*>(server_command),
                               geteuid(),       // server uid
                               true,
                               &server_port_);
  if (kr != BOOTSTRAP_SUCCESS) {
    PRINT_BOOTSTRAP_RESULT(kr, "bootstrap_create_server(): ");
    return kr;
  }

  strlcpy(service_name_, service_name, sizeof(service_name_));

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
  // Create a service called service_name, and return send rights to
  // that port in service_port_.
  kr = bootstrap_create_service(server_port_,
                                const_cast<char*>(service_name),
                                &service_port_);
#pragma clang diagnostic pop
  if (kr != BOOTSTRAP_SUCCESS) {
    PRINT_BOOTSTRAP_RESULT(kr, "bootstrap_create_service(): ");

    // perhaps the service has already been created - try to look it up
    kr = bootstrap_look_up(bootstrap_port, (char*)service_name, &service_port_);

    if (kr != BOOTSTRAP_SUCCESS) {
      PRINT_BOOTSTRAP_RESULT(kr, "bootstrap_look_up(): ");
      Unregister();  // clean up server port
      return kr;
    }
  }

  return KERN_SUCCESS;
}

//==============================================================================
OnDemandServer::~OnDemandServer() {
  if (unregister_on_cleanup_) {
    Unregister();
  }
}

//==============================================================================
void OnDemandServer::LaunchOnDemand() {
  // We need to do this, since the launched server is another process
  // and holding on to this port delays launching until the current process
  // exits!
  mach_port_deallocate(mach_task_self(), server_port_);
  server_port_ = MACH_PORT_DEAD;

  // Now, the service is still registered and all we need to do is send
  // a mach message to the service port in order to launch the server.
}

//==============================================================================
void OnDemandServer::Unregister() {
  if (service_port_ != MACH_PORT_NULL) {
    mach_port_deallocate(mach_task_self(), service_port_);
    service_port_ = MACH_PORT_NULL;
  }

  if (server_port_ != MACH_PORT_NULL) {
    // unregister the service
    kern_return_t kr = breakpad::BootstrapRegister(server_port_,
                                                   service_name_,
                                                   MACH_PORT_NULL);

    if (kr != KERN_SUCCESS) {
      PRINT_MACH_RESULT(kr, "Breakpad UNREGISTER : bootstrap_register() : ");
    }

    mach_port_deallocate(mach_task_self(), server_port_);
    server_port_ = MACH_PORT_NULL;
  }
}
