// 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.

#include <mach/mach.h>
#include <servers/bootstrap.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>

//==============================================================================
// class OnDemandServer :
//    A basic on-demand server launcher supporting a single named service port
//
// Example Usage :
//
//  kern_return_t result;
//  OnDemandServer *server = OnDemandServer::Create("/tmp/myserver",
//                                                  "com.MyCompany.MyServiceName",
//                                                  true,
//                                                  &result);
//
//  if (server) {
//    server->LaunchOnDemand();
//    mach_port_t service_port = GetServicePort();
//
//    // Send a mach message to service_port and "myserver" will be launched
//  }
//
//
//                  ---- Now in the server code ----
//
//  // "myserver" should get the service port and read the message which
//  // launched it:
//  mach_port_t service_rcv_port_;
//  kern_return_t kr = bootstrap_check_in(bootstrap_port,
//                                      "com.MyCompany.MyServiceName",
//                                      &service_rcv_port_);
//  // mach_msg() read service_rcv_port_ ....
//
//  ....
//
//  // Later "myserver" may want to unregister the service if it doesn't
//  // want its bootstrap service to stick around after it exits.
//
//  // DO NOT use mach_port_deallocate() here -- it will fail and the
//  // following bootstrap_register() will also fail leaving our service
//  // name hanging around forever (until reboot)
//  kern_return_t kr = mach_port_destroy(mach_task_self(), service_rcv_port_);
//
//  kr = bootstrap_register(bootstrap_port,
//                          "com.MyCompany.MyServiceName",
//                          MACH_PORT_NULL);

class OnDemandServer {
 public:
  // must call Initialize() to be useful
  OnDemandServer()
    : server_port_(MACH_PORT_NULL),
      service_port_(MACH_PORT_NULL),
      unregister_on_cleanup_(true) {
  }

  // Creates the bootstrap server and service
  kern_return_t Initialize(const char *server_command,
                           const char *service_name,
                           bool unregister_on_cleanup);

  // Returns an OnDemandServer object if successful, or NULL if there's
  // an error.  The error result will be returned in out_result.
  //
  //    server_command : the full path name including optional command-line
  //      arguments to the executable representing the server
  //
  //    service_name : represents service name
  //      something like "com.company.ServiceName"
  //
  //    unregister_on_cleanup : if true, unregisters the service name
  //      when the OnDemandServer is deleted -- unregistering will
  //      ONLY be possible if LaunchOnDemand() has NOT been called.
  //      If false, then the service will continue to be registered
  //      even after the current process quits.
  //
  //    out_result : if non-NULL, returns the result
  //      this value will be KERN_SUCCESS if Create() returns non-NULL
  //
  static OnDemandServer *Create(const char *server_command,
                                const char *service_name,
                                bool unregister_on_cleanup,
                                kern_return_t *out_result);

  // Cleans up and if LaunchOnDemand() has not yet been called then
  // the bootstrap service will be unregistered.
  ~OnDemandServer();

  // This must be called if we intend to commit to launching the server
  // by sending a mach message to our service port.  Do not call it otherwise
  // or it will be difficult (impossible?) to unregister the service name.
  void LaunchOnDemand();

  // This is the port we need to send a mach message to after calling
  // LaunchOnDemand().  Sending a message causing an immediate launch
  // of the server
  mach_port_t GetServicePort() { return service_port_; };

 private:
  // Disallow copy constructor
  OnDemandServer(const OnDemandServer&);

  // Cleans up and if LaunchOnDemand() has not yet been called then
  // the bootstrap service will be unregistered.
  void Unregister();

  name_t      service_name_;

  mach_port_t server_port_;
  mach_port_t service_port_;
  bool        unregister_on_cleanup_;
};
