New config, C++ Listener API
authorcantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Thu, 18 Mar 2004 19:03:27 +0000 (19:03 +0000)
committercantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Thu, 18 Mar 2004 19:03:27 +0000 (19:03 +0000)
git-svn-id: https://svn.middleware.georgetown.edu/cpp-sp/trunk@846 cb58f699-b61c-0410-a6fe-9272a202ed29

shar/Makefile.am
shar/shar-utils.cpp
shar/shar-utils.h
shar/shar.c [deleted file]
shar/shar.cpp [new file with mode: 0644]
shar/shar.dsp
shar/shar_win32.cpp

index f42e1c6..266e6d3 100644 (file)
@@ -12,7 +12,7 @@ endif
 
 test_client_SOURCES = test-client.c
 
-shar_SOURCES = shar.c shar-utils.cpp
+shar_SOURCES = shar.cpp shar-utils.cpp
 noinst_HEADERS = shar-utils.h
 
 test_client_LDADD = \
index d30bee7..e3e9a8d 100644 (file)
 #include <signal.h>
 
 #include "shar-utils.h"
+
 #include <shib/shib-threads.h>
-#include <shib-target/ccache-utils.h>
+#include <log4cpp/Category.hh>
 
 #ifdef USE_OUR_ONCRPC
 # define svc_fdset onc_svc_fdset
 #endif
 
 using namespace std;
+using namespace saml;
 using namespace shibboleth;
 using namespace shibtarget;
-
-//
-// PRIVATE interfaces
-//
-
-class SharChild {
-public:
-  SharChild(ShibSocket, const ShibRPCProtocols protos[], int numprotos);
-  ~SharChild();
-
-  void run();
-
-  ShibSocket   sock;
-  const ShibRPCProtocols *protos;
-  int          numprotos;
-
-  Thread*      child;
-  Mutex*       lock;
-};
+using namespace log4cpp;
 
 namespace {
   map<Thread*,int> children;
@@ -60,29 +44,31 @@ namespace {
   bool         running;
 };
 
-void*
-shar_client_thread (void* arg)
+void* shar_client_thread (void* arg)
 {
   SharChild* child = (SharChild*)arg;
 
   // First, let's block all signals
   Thread::mask_all_signals();
 
-  g_shibTargetCCache->thread_init();
+  ShibTargetConfig::getConfig().getINI()->getSessionCache()->thread_init();
 
   // the run the child until they exit.
   child->run();
 
-  g_shibTargetCCache->thread_end();
+  ShibTargetConfig::getConfig().getINI()->getSessionCache()->thread_end();
 
   // now we can clean up and exit the thread.
   delete child;
   return NULL;
 }
 
-SharChild::SharChild(ShibSocket a_sock, const ShibRPCProtocols a_protos[], int a_numprotos)
-  : sock(a_sock), protos(a_protos), numprotos(a_numprotos)
+SharChild::SharChild(IListener::ShibSocket& s, const Iterator<ShibRPCProtocols>& protos) : sock(s)
 {
+  protos.reset();
+  while (protos.hasNext())
+    v_protos.push_back(protos.next());
+  
   // Create the lock and then lock this child
   lock = Mutex::create();
   Lock tl(lock);
@@ -110,7 +96,8 @@ SharChild::~SharChild()
 
 void SharChild::run()
 {
-  if (shar_create_svc(sock, protos, numprotos) != 0)
+  NDC ndc("run");
+  if (SHARUtils::shar_create_svc(sock, v_protos) != 0)
     return;
 
   fd_set readfds;
@@ -125,7 +112,7 @@ void SharChild::run()
 
     case -1:
       if (errno == EINTR) continue;
-      perror ("SharChild::run(): - select failed");
+      SHARUtils::log_error();
       return;
 
     case 0:
@@ -137,34 +124,59 @@ void SharChild::run()
   }
 
   if (running) {
+      ShibTargetConfig::getConfig().getINI()->getListener()->close(sock);
+  }
+}
+
+void SHARUtils::log_error()
+{
 #ifdef WIN32
-      closesocket(sock);
+    int rc=WSAGetLastError();
 #else
-      close(sock);
+    int rc=errno;
+#endif
+#ifdef HAVE_STRERROR_R
+    char buf[256];
+    strerror_r(rc,buf,sizeof(buf));
+    buf[255]=0;
+    Category::getInstance("SHAR.SHARUtils").error("system call resulted in error (%d): %s",rc,buf);
+#else
+    Category::getInstance("SHAR.SHARUtils").error("system call resulted in error (%d): %s",rc,strerror(rc));
 #endif
-  }
 }
 
-//
-// PUBLIC interfaces -- used by SHAR
-//
-
-extern "C" void
-shar_new_connection(ShibSocket sock, const ShibRPCProtocols protos[], int numprotos)
+int SHARUtils::shar_create_svc(IListener::ShibSocket& sock, const Iterator<ShibRPCProtocols>& protos)
 {
-  SharChild* child = new SharChild(sock, protos, numprotos);
+  NDC ndc("shar_create_svc");
+
+  /* Wrap an RPC Service around the new connection socket */
+  SVCXPRT* svc = svcfd_create (sock, 0, 0);
+  if (!svc) {
+    Category::getInstance("SHAR.SHARUtils").error("cannot create RPC listener");
+    return -1;
+  }
+
+  /* Register the SHIBRPC RPC Program */
+  while (protos.hasNext()) {
+    const ShibRPCProtocols& p=protos.next();
+    if (!svc_register (svc, p.prog, p.vers, p.dispatch, 0)) {
+      svc_destroy(svc);
+      ShibTargetConfig::getConfig().getINI()->getListener()->close(sock);
+      Category::getInstance("SHAR.SHARUtils").error("cannot register RPC program");
+      return -2;
+    }
+  }
+  return 0;
 }
 
-extern "C" void
-shar_utils_init()
+void SHARUtils::init()
 {
   child_lock = Mutex::create();
   child_wait = CondWait::create();
   running = true;
 }
 
-extern "C" void
-shar_utils_fini()
+void SHARUtils::fini()
 {
   running = false;
 
index 4dccd33..da310b0 100644 (file)
@@ -1,3 +1,52 @@
+/* 
+ * The Shibboleth License, Version 1. 
+ * Copyright (c) 2002 
+ * University Corporation for Advanced Internet Development, 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, if any, must include 
+ * the following acknowledgment: "This product includes software developed by 
+ * the University Corporation for Advanced Internet Development 
+ * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement 
+ * may appear in the software itself, if and wherever such third-party 
+ * acknowledgments normally appear.
+ * 
+ * Neither the name of Shibboleth nor the names of its contributors, nor 
+ * Internet2, nor the University Corporation for Advanced Internet Development, 
+ * Inc., nor UCAID may be used to endorse or promote products derived from this 
+ * software without specific prior written permission. For written permission, 
+ * please contact shibboleth@shibboleth.org
+ * 
+ * Products derived from this software may not be called Shibboleth, Internet2, 
+ * UCAID, or the University Corporation for Advanced Internet Development, nor 
+ * may Shibboleth appear in their name, without prior written permission of the 
+ * University Corporation for Advanced Internet Development.
+ * 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+ * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK 
+ * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE. 
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY 
+ * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. 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.
+ */
+
 /*
  * shar-utils.h -- header file for the SHAR utilities.
  *
 
 #include <shib-target/shib-target.h>
 
-#ifdef __cplusplus
 extern "C" {
-#endif
+    typedef void (*dispatch_fn)(struct svc_req* rqstp, register SVCXPRT* transp);
+}
 
-typedef struct {
-  u_long prog;
-  u_long vers;
-  void (*dispatch)();
-} ShibRPCProtocols;
+struct ShibRPCProtocols
+{
+    u_long prog;
+    u_long vers;
+    dispatch_fn dispatch;
+};
 
+class SharChild {
+public:
+    SharChild(shibtarget::IListener::ShibSocket& s, const saml::Iterator<ShibRPCProtocols>& protos);
+    ~SharChild();
+    void run();
 
-int shar_create_svc(ShibSocket sock,const ShibRPCProtocols protos[],int numprotos);
-void shar_new_connection(ShibSocket sock, const ShibRPCProtocols protos[],
-                        int numprotos);
-void shar_utils_init();
-void shar_utils_fini();
+private:
+    shibtarget::IListener::ShibSocket sock;
+    std::vector<ShibRPCProtocols> v_protos;
+    shibboleth::Thread* child;
+    shibboleth::Mutex* lock;
+};
 
-#ifdef __cplusplus
-}
-#endif
+struct SHARUtils
+{
+    static void init();
+    static void fini();
+    static int shar_create_svc(shibtarget::IListener::ShibSocket& s, const saml::Iterator<ShibRPCProtocols>& protos);
+    static void log_error();
+};
 
 #endif /* SHAR_UTILS_H */
diff --git a/shar/shar.c b/shar/shar.c
deleted file mode 100644 (file)
index aff7cd9..0000000
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * The Shibboleth License, Version 1.
- * Copyright (c) 2002
- * University Corporation for Advanced Internet Development, 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, if any, must include
- * the following acknowledgment: "This product includes software developed by
- * the University Corporation for Advanced Internet Development
- * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
- * may appear in the software itself, if and wherever such third-party
- * acknowledgments normally appear.
- *
- * Neither the name of Shibboleth nor the names of its contributors, nor
- * Internet2, nor the University Corporation for Advanced Internet Development,
- * Inc., nor UCAID may be used to endorse or promote products derived from this
- * software without specific prior written permission. For written permission,
- * please contact shibboleth@shibboleth.org
- *
- * Products derived from this software may not be called Shibboleth, Internet2,
- * UCAID, or the University Corporation for Advanced Internet Development, nor
- * may Shibboleth appear in their name, without prior written permission of the
- * University Corporation for Advanced Internet Development.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
- * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
- * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. 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.
- */
-
-/*
- * shar.c -- the SHAR "main" code.  All the functionality is elsewhere
- *           (in case you want to turn this into a library later).
- *
- * Created By: Derek Atkins <derek@ihtfp.com>
- *
- * $Id$
- */
-
-// eventually we might be able to support autoconf via cygwin...
-#if defined (_MSC_VER) || defined(__BORLANDC__)
-# include "config_win32.h"
-#else
-# include "config.h"
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#include <sys/select.h>
-#endif
-
-#include <stdio.h>
-#include <errno.h>
-#include <signal.h>
-
-#include "shar-utils.h"
-
-#ifndef FD_SETSIZE
-# define FD_SETSIZE 1024
-#endif
-
-void shibrpc_prog_1(struct svc_req *rqstp, register SVCXPRT *transp);
-
-#ifdef NEED_SVCFD_CREATE_DEFN
-extern SVCXPRT* svcfd_create ();
-#endif
-
-int shar_run = 1;
-static const char* config = NULL;
-static int unlink_socket = 0;
-#if 0
-static int foreground = 0;
-#endif
-
-int shar_create_svc(ShibSocket sock, const ShibRPCProtocols protos[], int numprotos)
-{
-  int i;
-  SVCXPRT *svc;
-
-  /* Wrap an RPC Service around the new connection socket */
-  svc = svcfd_create (sock, 0, 0);
-  if (!svc) {
-    fprintf (stderr, "Cannot create RPC Listener\n");
-    return -1;
-  }
-
-  /* Register the SHIBRPC RPC Program */
-  for (i = 0; i < numprotos; i++) {
-    if (!svc_register (svc, protos[i].prog, protos[i].vers,
-                      protos[i].dispatch, 0)) {
-      svc_destroy(svc);
-#ifdef WIN32
-      closesocket(sock);
-#else
-      close(sock);
-#endif
-      fprintf (stderr, "Cannot register RPC Program\n");
-      return -2;
-    }
-  }
-  return 0;
-}
-
-static int new_connection(ShibSocket listener, const ShibRPCProtocols protos[], int numproto)
-{
-  ShibSocket sock;
-
-  /* Accept the connection */
-  if (shib_sock_accept(listener, &sock)) {
-    fprintf(stderr, "ACCEPT failed\n");
-    return -1;
-  }
-
-  shar_new_connection(sock, protos, numproto);
-  return 0;
-}
-
-static void shar_svc_run(ShibSocket listener, const ShibRPCProtocols protos[], int numproto)
-{
-  fd_set readfds;
-  struct timeval tv = { 0, 0 };
-
-  while (shar_run) {
-    FD_ZERO(&readfds);
-    FD_SET(listener, &readfds);
-    tv.tv_sec = 5;
-
-    switch (select(FD_SETSIZE, &readfds, 0, 0, &tv)) {
-
-    case -1:
-      if (errno == EINTR) continue;
-      perror("shar_svc_run: - select failed");
-      return;
-
-    case 0:
-      continue;
-
-    default:
-      new_connection(listener, protos, numproto);
-    }
-  }
-  printf ("shar_svc_run ended\n");
-}
-
-#ifdef WIN32
-
-int real_main(const char* arg, int preinit)
-{
-  static ShibSocket sock;
-  ShibRPCProtocols protos[] = {
-    { SHIBRPC_PROG, SHIBRPC_VERS_1, shibrpc_prog_1 }
-  };
-
-  if (preinit)
-  {
-      config=arg;
-      if (!config)
-        config=getenv("SHIBCONFIG");
-
-      /* initialize the shib-target library */
-      if (shib_target_initialize(SHIBTARGET_SHAR, config))
-        return -2;
-
-      /* Create the SHAR listener socket */
-      if (shib_sock_create(&sock) != 0)
-        return -3;
-
-      /* Bind to the proper port */
-      if (shib_sock_bind(sock, shib_target_sockname()) != 0)
-        return -4;
-
-      /* Initialize the SHAR Utilitites */
-      shar_utils_init();
-  }
-  else
-  {
-      /* Run the listener */
-      shar_svc_run(sock, protos, 1);
-
-      /* Finalize the SHAR, close all clients */
-      shar_utils_fini();
-
-      shib_sock_close(sock, shib_target_sockname());
-
-      shib_target_finalize();
-      fprintf(stderr, "shar_svc_run returned.\n");
-  }
-  return 0;
-}
-
-#else
-
-static void term_handler(int arg)
-{
-  shar_run = 0;
-}
-
-static int setup_signals(void)
-{
-  struct sigaction sa;
-
-  memset(&sa, 0, sizeof (sa));
-  sa.sa_handler = SIG_IGN;
-  sa.sa_flags = SA_RESTART;
-
-  if (sigaction(SIGPIPE, &sa, NULL) < 0) {
-    perror ("sigaction SIGPIPE");
-    return -1;
-  }
-
-  memset(&sa, 0, sizeof (sa));
-  sa.sa_handler = term_handler;
-  sa.sa_flags = SA_RESTART;
-
-  if (sigaction(SIGHUP, &sa, NULL) < 0) {
-    perror ("sigaction SIGHUP");
-    return -1;
-  }
-  if (sigaction(SIGINT, &sa, NULL) < 0) {
-    perror ("sigaction SIGINT");
-    return -1;
-  }
-  if (sigaction(SIGQUIT, &sa, NULL) < 0) {
-    perror ("sigaction SIGQUIT");
-    return -1;
-  }
-  if (sigaction(SIGTERM, &sa, NULL) < 0) {
-    perror ("sigaction SIGTERM");
-    return -1;
-  }
-  return 0;
-}
-
-static void usage(char* whoami)
-{
-  fprintf (stderr, "usage: %s [-f]\n", whoami);
-  fprintf (stderr, "  -c\tconfig file to use.\n");
-  fprintf (stderr, "  -f\tforce removal of listener socket.\n");
-#if 0
-  fprintf (stderr, "  -F\trun in the foreground.\n");
-#endif
-  fprintf (stderr, "  -h\tprint this help message.\n");
-  exit (1);
-}
-
-static int parse_args(int argc, char* argv[])
-{
-  int opt;
-
-  while ((opt = getopt(argc, argv, "cfFh")) > 0) {
-    switch (opt) {
-    case 'c':
-      config=optarg;
-      break;
-    case 'f':
-      unlink_socket = 1;
-      break;
-#if 0
-    case 'F':
-      foreground++;
-      break;
-#endif
-    default:
-      return -1;
-    }
-  }
-  return 0;
-}
-
-int main(int argc, char *argv[])
-{
-  ShibSocket sock;
-  ShibRPCProtocols protos[] = {
-    { SHIBRPC_PROG, SHIBRPC_VERS_1, shibrpc_prog_1 }
-  };
-
-  if (setup_signals() != 0)
-    return -1;
-
-  if (parse_args(argc, argv) != 0)
-    usage(argv[0]);
-
-  if (!config)
-    config=getenv("SHIBCONFIG");
-
-  /* initialize the shib-target library */
-  if (shib_target_initialize(SHIBTARGET_SHAR, config))
-    return -2;
-
-  if (unlink_socket && *(shib_target_sockname())=='/')
-      unlink(shib_target_sockname());
-
-  /* Create the SHAR listener socket */
-  if (shib_sock_create(&sock) != 0)
-    return -3;
-
-  /* Bind to the proper port */
-  if (shib_sock_bind(sock, shib_target_sockname()) != 0)
-    return -4;
-
-#if 0
-  /* (maybe) Put myself into the background. */
-  if (!foreground)
-    daemon(0, 1);              /* chdir to /, but do not redirect stdout/stderr */
-#endif
-
-  /* Initialize the SHAR Utilitites */
-  shar_utils_init();
-
-  /* Run the listener */
-  shar_svc_run(sock, protos, 1);
-
-  /* Finalize the SHAR, close all clients */
-  shar_utils_fini();
-  fprintf(stderr, "shar utils finalized\n");
-
-  shib_sock_close(sock, shib_target_sockname());
-  fprintf(stderr, "shib socket closed\n");
-
-  shib_target_finalize();
-  fprintf(stderr, "shar finished.  bye bye.\n");
-  return 0;
-}
-
-#endif
diff --git a/shar/shar.cpp b/shar/shar.cpp
new file mode 100644 (file)
index 0000000..226b731
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ * The Shibboleth License, Version 1.
+ * Copyright (c) 2002
+ * University Corporation for Advanced Internet Development, 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, if any, must include
+ * the following acknowledgment: "This product includes software developed by
+ * the University Corporation for Advanced Internet Development
+ * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
+ * may appear in the software itself, if and wherever such third-party
+ * acknowledgments normally appear.
+ *
+ * Neither the name of Shibboleth nor the names of its contributors, nor
+ * Internet2, nor the University Corporation for Advanced Internet Development,
+ * Inc., nor UCAID may be used to endorse or promote products derived from this
+ * software without specific prior written permission. For written permission,
+ * please contact shibboleth@shibboleth.org
+ *
+ * Products derived from this software may not be called Shibboleth, Internet2,
+ * UCAID, or the University Corporation for Advanced Internet Development, nor
+ * may Shibboleth appear in their name, without prior written permission of the
+ * University Corporation for Advanced Internet Development.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
+ * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
+ * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. 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.
+ */
+
+/*
+ * shar.cpp -- the SHAR "main" code.  All the functionality is elsewhere
+ *           (in case you want to turn this into a library later).
+ *
+ * Created By: Derek Atkins <derek@ihtfp.com>
+ *
+ * $Id$
+ */
+
+// eventually we might be able to support autoconf via cygwin...
+#if defined (_MSC_VER) || defined(__BORLANDC__)
+# include "config_win32.h"
+#else
+# include "config.h"
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#include <sys/select.h>
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include <signal.h>
+
+#include "shar-utils.h"
+
+using namespace std;
+using namespace saml;
+using namespace shibboleth;
+using namespace shibtarget;
+
+#ifndef FD_SETSIZE
+# define FD_SETSIZE 1024
+#endif
+
+extern "C" void shibrpc_prog_1(struct svc_req* rqstp, register SVCXPRT* transp);
+
+#ifdef NEED_SVCFD_CREATE_DEFN
+extern SVCXPRT* svcfd_create ();
+#endif
+
+int shar_run = 1;
+const char* config = NULL;
+const char* schemadir = NULL;
+static int unlink_socket = 0;
+
+static bool new_connection(IListener::ShibSocket& listener, const Iterator<ShibRPCProtocols>& protos)
+{
+    IListener::ShibSocket sock;
+
+    // Accept the connection.
+    if (ShibTargetConfig::getConfig().getINI()->getListener()->accept(listener, sock))
+        return false;
+
+    // We throw away the result because the children manage themselves...
+    new SharChild(sock,protos);
+    return true;
+}
+
+static void shar_svc_run(IListener::ShibSocket& listener, const Iterator<ShibRPCProtocols>& protos)
+{
+    NDC ndc("shar_svc_run");
+
+    while (shar_run) {
+        fd_set readfds;
+        FD_ZERO(&readfds);
+        FD_SET(listener, &readfds);
+        struct timeval tv = { 0, 0 };
+        tv.tv_sec = 5;
+    
+        switch (select(FD_SETSIZE, &readfds, 0, 0, &tv)) {
+            case -1:
+                if (errno == EINTR) continue;
+                SHARUtils::log_error();
+                return;
+        
+            case 0:
+                continue;
+        
+            default:
+                new_connection(listener, protos);
+        }
+    }
+    printf("shar_svc_run ended\n");
+}
+
+#ifdef WIN32
+
+int real_main(int preinit)
+{
+    static IListener::ShibSocket sock;
+    ShibRPCProtocols protos[1] = {
+        { SHIBRPC_PROG, SHIBRPC_VERS_1, shibrpc_prog_1 }
+    };
+
+    ShibTargetConfig& conf=ShibTargetConfig::getConfig();
+    if (preinit) {
+
+        // initialize the shib-target library
+        conf.setFeatures(
+            ShibTargetConfig::Listener |
+            ShibTargetConfig::SessionCache |
+            ShibTargetConfig::Metadata |
+            ShibTargetConfig::Trust |
+            ShibTargetConfig::Credentials |
+            ShibTargetConfig::AAP |
+            ShibTargetConfig::SHARExtensions
+            );
+        if (!config)
+            config=getenv("SHIBCONFIG");
+        if (!schemadir)
+            schemadir=getenv("SHIBSCHEMAS");
+        if (!conf.init(schemadir,config))
+            return -2;
+
+        const IListener* listener=conf.getINI()->getListener();
+        
+        // Create the SHAR listener socket
+        if (!listener->create(sock))
+            return -3;
+
+        // Bind to the proper port
+        if (!listener->bind(sock))
+            return -4;
+
+        // Initialize the SHAR Utilitites
+        SHARUtils::init();
+    }
+    else {
+        // Run the listener
+        shar_svc_run(sock, ArrayIterator<ShibRPCProtocols>(protos,1));
+        fprintf(stderr,"shar_svc_run returned\n");
+
+        // Finalize the SHAR, close all clients
+        SHARUtils::fini();
+        conf.getINI()->getListener()->close(sock);
+        conf.shutdown();
+    }
+    return 0;
+}
+
+#else
+
+static void term_handler(int arg)
+{
+    shar_run = 0;
+}
+
+static int setup_signals(void)
+{
+    NDC ndc("setup_signals");
+    
+    struct sigaction sa;
+    memset(&sa, 0, sizeof (sa));
+    sa.sa_handler = SIG_IGN;
+    sa.sa_flags = SA_RESTART;
+
+    if (sigaction(SIGPIPE, &sa, NULL) < 0) {
+        SHARUtils::log_error();
+        return -1;
+    }
+
+    memset(&sa, 0, sizeof (sa));
+    sa.sa_handler = term_handler;
+    sa.sa_flags = SA_RESTART;
+
+    if (sigaction(SIGHUP, &sa, NULL) < 0) {
+        SHARUtils::log_error();
+        return -1;
+    }
+    if (sigaction(SIGINT, &sa, NULL) < 0) {
+        SHARUtils::log_error();
+        return -1;
+    }
+    if (sigaction(SIGQUIT, &sa, NULL) < 0) {
+        SHARUtils::log_error();
+        return -1;
+    }
+    if (sigaction(SIGTERM, &sa, NULL) < 0) {
+        SHARUtils::log_error();
+        return -1;
+    }
+    return 0;
+}
+
+static void usage(char* whoami)
+{
+    fprintf(stderr, "usage: %s [-f]\n", whoami);
+    fprintf(stderr, "  -c\tconfig file to use.\n");
+    fprintf(stderr, "  -f\tforce removal of listener socket.\n");
+    fprintf(stderr, "  -h\tprint this help message.\n");
+    exit(1);
+}
+
+static int parse_args(int argc, char* argv[])
+{
+    int opt;
+
+    while ((opt = getopt(argc, argv, "cfFh")) > 0) {
+        switch (opt) {
+            case 'c':
+                config=optarg;
+                break;
+            case 'd':
+                schemadir=optarg;
+                break;
+            case 'f':
+                unlink_socket = 1;
+                break;
+            default:
+                return -1;
+        }
+    }
+    return 0;
+}
+
+int main(int argc, char *argv[])
+{
+    IListener::ShibSocket sock;
+    ShibRPCProtocols protos[] = {
+        { SHIBRPC_PROG, SHIBRPC_VERS_1, shibrpc_prog_1 }
+    };
+
+    if (setup_signals() != 0)
+        return -1;
+
+    if (parse_args(argc, argv) != 0)
+        usage(argv[0]);
+
+    if (!schemadir)
+        schemadir=getenv("SHIBSCHEMAS");
+    if (!config)
+        config=getenv("SHIBCONFIG");
+
+    // initialize the shib-target library
+    ShibTargetConfig& conf=ShibTargetConfig::getConfig();
+    conf.setFeatures(
+        ShibTargetConfig::Listener |
+        ShibTargetConfig::SessionCache |
+        ShibTargetConfig::Metadata |
+        ShibTargetConfig::Trust |
+        ShibTargetConfig::Credentials |
+        ShibTargetConfig::AAP |
+        ShibTargetConfig::SHARExtensions
+        );
+    if (!conf.init(schemadir,config))
+        return -2;
+
+    IListener* listener=conf.getINI()->getListener();
+    
+    // Create the SHAR listener socket
+    if (!listener->create(&sock))
+        return -3;
+
+    // Bind to the proper port
+    if (!listener->bind(sock, unlink_socket==1))
+        return -4;
+
+    // Initialize the SHAR Utilitites
+    SHARUtils::init();
+
+    // Run the listener
+    shar_svc_run(sock, ArrayIterator<ShibRPCProtocols>);
+
+    /* Finalize the SHAR, close all clients */
+    SHARUtils::fini();
+    fprintf(stderr, "shar utils finalized\n");
+
+    listener->close(sock);
+    fprintf(stderr, "shib socket closed\n");
+
+    conf.shutdown();
+    fprintf(stderr, "shar finished.  bye bye.\n");
+    return 0;
+}
+
+#endif
index 9913e73..7b88eab 100644 (file)
@@ -50,7 +50,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 wsock32.lib advapi32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 wsock32.lib advapi32.lib saml_4.lib log4cpp.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\opensaml\c\saml\Release"
 
 !ELSEIF  "$(CFG)" == "shar - Win32 Debug"
 
@@ -74,7 +74,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 wsock32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 wsock32.lib advapi32.lib saml_4D.lib log4cppD.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\opensaml\c\saml\Debug"
 
 !ENDIF 
 
@@ -92,7 +92,7 @@ SOURCE=".\shar-utils.h"
 # End Source File
 # Begin Source File
 
-SOURCE=.\shar.c
+SOURCE=.\shar.cpp
 # End Source File
 # Begin Source File
 
index 56123d2..6de5179 100644 (file)
@@ -58,7 +58,9 @@
 #include "config_win32.h"
 #include "shar-utils.h"
 
-extern "C" int shar_run;                    // signals shutdown to Unix side
+extern int shar_run;                    // signals shutdown to Unix side
+extern const char* schemadir;
+extern const char* config;
 
 // internal variables
 SERVICE_STATUS          ssStatus;       // current status of the service
@@ -66,7 +68,6 @@ SERVICE_STATUS_HANDLE   sshStatusHandle;
 DWORD                   dwErr = 0;
 BOOL                    bConsole = FALSE;
 char                    szErr[256];
-LPCSTR                  lpszConfig = NULL;
 LPCSTR                  lpszInstall = NULL;
 LPCSTR                  lpszRemove = NULL;
 
@@ -102,7 +103,7 @@ BOOL WINAPI BreakHandler(DWORD dwCtrlType)
 }
 
 
-extern "C" int real_main(const char*, int);  // The revised two-phase main() in shar.c
+int real_main(int);  // The revised two-phase main() in shar.cpp
 
 int main(int argc, char *argv[])
 {
@@ -127,7 +128,12 @@ int main(int argc, char *argv[])
         else if (_stricmp( "config", argv[i]+1) == 0)
         {
             if (argc > ++i)
-                lpszConfig = argv[i++];
+                config = argv[i++];
+        }
+        else if (_stricmp( "schemadir", argv[i]+1) == 0)
+        {
+            if (argc > ++i)
+                schemadir = argv[i++];
         }
         else
         {
@@ -139,12 +145,12 @@ int main(int argc, char *argv[])
     {
         // Install break handler, then run the C routine twice, once to setup, once to start running.
         SetConsoleCtrlHandler(&BreakHandler,TRUE);
-        if (real_main(lpszConfig,1)!=0)
+        if (real_main(1)!=0)
         {
             LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, "SHAR startup failed, check shar log for help.");
             return -1;
         }
-        return real_main(lpszConfig,0);
+        return real_main(0);
     }
     else if (lpszInstall)
     {
@@ -166,7 +172,8 @@ int main(int argc, char *argv[])
         printf("%s -install <name>   to install the named service\n", argv[0]);
         printf("%s -remove <name>    to remove the named service\n", argv[0]);
         printf("%s -console          to run as a console app for debugging\n", argv[0]);
-        printf("%s -config           to specify the config file to use\n", argv[0]);
+        printf("%s -config <file>    to specify the config file to use\n", argv[0]);
+        printf("%s -schemadir <dir>  to specify where schemas are\n", argv[0]);
         printf("\nService starting.\nThis may take several seconds. Please wait.\n" );
 
     SERVICE_TABLE_ENTRY dispatchTable[] =
@@ -189,7 +196,7 @@ int main(int argc, char *argv[])
 VOID ServiceStart (DWORD dwArgc, LPSTR *lpszArgv)
 {
 
-    if (real_main(lpszConfig,1)!=0)
+    if (real_main(1)!=0)
     {
         LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, "SHAR startup failed, check shar log for help.");
         return;
@@ -200,7 +207,7 @@ VOID ServiceStart (DWORD dwArgc, LPSTR *lpszArgv)
     if (!ReportStatusToSCMgr(SERVICE_RUNNING, NO_ERROR, 0))
         return;
 
-    real_main(lpszConfig,0);
+    real_main(0);
 }
 
 
@@ -358,7 +365,7 @@ void CmdInstallService(LPCSTR name)
     char szPath[256];
     char dispName[512];
     char realName[512];
-    char cmd[512];
+    char cmd[2048];
 
     if ( GetModuleFileName( NULL, szPath, 256 ) == 0 )
     {
@@ -368,9 +375,14 @@ void CmdInstallService(LPCSTR name)
     
     sprintf(dispName,"Shibboleth Attribute Requester (%s)",name);
     sprintf(realName,"SHAR_%s",name);
-    
-    if (lpszConfig)
-        sprintf(cmd,"%s -config %s",szPath,lpszConfig);
+    if (config && schemadir)
+        sprintf(cmd,"%s -config %s -schemadir %s",szPath,config,schemadir);
+    else if (config)
+        sprintf(cmd,"%s -config %s",szPath,config);
+    else if (schemadir)
+        sprintf(cmd,"%s -schemadir %s",szPath,schemadir);
+    else
+        sprintf(cmd,"%s",szPath);
 
     schSCManager = OpenSCManager(
                         NULL,                   // machine (NULL == local)
@@ -389,7 +401,7 @@ void CmdInstallService(LPCSTR name)
             SERVICE_WIN32_OWN_PROCESS,  // service type
             SERVICE_AUTO_START,         // start type
             SERVICE_ERROR_NORMAL,       // error control type
-            lpszConfig ? cmd : szPath,  // service's command line
+            cmd,                        // service's command line
             NULL,                       // no load ordering group
             NULL,                       // no tag identifier
             NULL,                       // dependencies