Renamed shar project, some Makefile fixes.
[shibboleth/sp.git] / shibd / shibd.cpp
diff --git a/shibd/shibd.cpp b/shibd/shibd.cpp
new file mode 100644 (file)
index 0000000..7b72b09
--- /dev/null
@@ -0,0 +1,338 @@
+/*\r
+ *  Copyright 2001-2007 Internet2\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/*\r
+ * shar.cpp -- the shibd "main" code.  All the functionality is elsewhere\r
+ *\r
+ * Created By: Derek Atkins <derek@ihtfp.com>\r
+ *\r
+ * $Id: shar.cpp 2164 2007-02-11 05:26:18 +0000 (Sun, 11 Feb 2007) cantor $\r
+ */\r
+\r
+\r
+// eventually we might be able to support autoconf via cygwin...\r
+#if defined (_MSC_VER) || defined(__BORLANDC__)\r
+# include "config_win32.h"\r
+#else\r
+# include "config.h"\r
+#endif\r
+\r
+#ifdef WIN32\r
+# define _CRT_NONSTDC_NO_DEPRECATE 1\r
+# define _CRT_SECURE_NO_DEPRECATE 1\r
+#endif\r
+\r
+#include <shibsp/SPConfig.h>\r
+\r
+#ifdef HAVE_UNISTD_H\r
+#include <unistd.h>\r
+#include <sys/select.h>\r
+#endif\r
+\r
+#include <stdio.h>\r
+#include <signal.h>\r
+#include <log4cpp/Category.hh>\r
+#include <shibsp/ServiceProvider.h>\r
+#include <shibsp/remoting/ListenerService.h>\r
+#include <xercesc/util/XMLUniDefs.hpp>\r
+#include <xmltooling/XMLToolingConfig.h>\r
+#include <xmltooling/util/XMLHelper.h>\r
+\r
+using namespace shibsp;\r
+using namespace log4cpp;\r
+using namespace xmltooling;\r
+using namespace std;\r
+\r
+bool shibd_shutdown = false;\r
+const char* shar_config = NULL;\r
+const char* shar_schemadir = NULL;\r
+bool shar_checkonly = false;\r
+static int unlink_socket = 0;\r
+const char* pidfile = NULL;\r
+\r
+#ifdef WIN32\r
+\r
+//#include <CRTDBG.H>\r
+\r
+#define nNoMansLandSize 4\r
+typedef struct _CrtMemBlockHeader\r
+{\r
+        struct _CrtMemBlockHeader * pBlockHeaderNext;\r
+        struct _CrtMemBlockHeader * pBlockHeaderPrev;\r
+        char *                      szFileName;\r
+        int                         nLine;\r
+        size_t                      nDataSize;\r
+        int                         nBlockUse;\r
+        long                        lRequest;\r
+        unsigned char               gap[nNoMansLandSize];\r
+        /* followed by:\r
+         *  unsigned char           data[nDataSize];\r
+         *  unsigned char           anotherGap[nNoMansLandSize];\r
+         */\r
+} _CrtMemBlockHeader;\r
+\r
+/*\r
+int MyAllocHook(int nAllocType, void *pvData,\r
+      size_t nSize, int nBlockUse, long lRequest,\r
+      const unsigned char * szFileName, int nLine)\r
+{\r
+    if ( nBlockUse == _CRT_BLOCK )\r
+      return( TRUE );\r
+    if (nAllocType == _HOOK_FREE) {\r
+        _CrtMemBlockHeader* ptr = (_CrtMemBlockHeader*)(((_CrtMemBlockHeader *)pvData)-1);\r
+        if (ptr->nDataSize == 8192)\r
+            fprintf(stderr,"free  request %u size %u\n", ptr->lRequest, ptr->nDataSize);\r
+    }\r
+    else if (nAllocType == _HOOK_ALLOC && nSize == 8192)\r
+        fprintf(stderr,"%s request %u size %u\n", ((nAllocType == _HOOK_ALLOC) ? "alloc" : "realloc"), lRequest, nSize);\r
+    return (TRUE);\r
+}\r
+*/\r
+\r
+int real_main(int preinit)\r
+{\r
+    SPConfig& conf=SPConfig::getConfig();\r
+    if (preinit) {\r
+\r
+        // Initialize the SP library.\r
+        conf.setFeatures(\r
+            SPConfig::Listener |\r
+            SPConfig::Caching |\r
+            SPConfig::Metadata |\r
+            SPConfig::Trust |\r
+            SPConfig::Credentials |\r
+            SPConfig::AttributeResolver |\r
+            SPConfig::OutOfProcess |\r
+            (shar_checkonly ? (SPConfig::InProcess | SPConfig::RequestMapping) : SPConfig::Logging)\r
+            );\r
+        if (!shar_config)\r
+            shar_config=getenv("SHIBCONFIG");\r
+        if (!shar_schemadir)\r
+            shar_schemadir=getenv("SHIBSCHEMAS");\r
+        if (!shar_schemadir)\r
+            shar_schemadir=SHIBSP_SCHEMAS;\r
+        if (!shar_config)\r
+            shar_config=SHIBSP_CONFIG;\r
+        if (!conf.init(shar_schemadir)) {\r
+            fprintf(stderr, "configuration is invalid, see console for specific problems\n");\r
+            return -1;\r
+        }\r
+        \r
+        try {\r
+            fprintf(stderr, "loading configuration file: %s\n", shar_config);\r
+            static const XMLCh path[] = UNICODE_LITERAL_4(p,a,t,h);\r
+            static const XMLCh validate[] = UNICODE_LITERAL_8(v,a,l,i,d,a,t,e);\r
+            DOMDocument* dummydoc=XMLToolingConfig::getConfig().getParser().newDocument();\r
+            XercesJanitor<DOMDocument> docjanitor(dummydoc);\r
+            DOMElement* dummy = dummydoc->createElementNS(NULL,path);\r
+            auto_ptr_XMLCh src(shar_config);\r
+            dummy->setAttributeNS(NULL,path,src.get());\r
+            dummy->setAttributeNS(NULL,validate,xmlconstants::XML_ONE);\r
+    \r
+            conf.setServiceProvider(conf.ServiceProviderManager.newPlugin(XML_SERVICE_PROVIDER,dummy));\r
+            conf.getServiceProvider()->init();\r
+        }\r
+        catch (exception& ex) {\r
+            fprintf(stderr, "caught exception while loading configuration: %s\n", ex.what());\r
+            conf.term();\r
+            return -2;\r
+        }\r
+\r
+        // If just a test run, bail.\r
+        if (shar_checkonly) {\r
+            fprintf(stdout, "overall configuration is loadable, check console for non-fatal problems\n");\r
+            return 0;\r
+        }\r
+    }\r
+    else {\r
+\r
+        //_CrtSetAllocHook(MyAllocHook);\r
+\r
+        // Run the listener\r
+        if (!shar_checkonly) {\r
+\r
+            // Run the listener.\r
+            if (!conf.getServiceProvider()->getListenerService()->run(&shibd_shutdown)) {\r
+                fprintf(stderr, "listener failed to enter listen loop\n");\r
+                return -3;\r
+            }\r
+        }\r
+\r
+        conf.term();\r
+    }\r
+    return 0;\r
+}\r
+\r
+#else\r
+\r
+static void term_handler(int arg)\r
+{\r
+    shibd_shutdown = true;\r
+}\r
+\r
+static int setup_signals(void)\r
+{\r
+    struct sigaction sa;\r
+    memset(&sa, 0, sizeof (sa));\r
+    sa.sa_handler = SIG_IGN;\r
+    sa.sa_flags = SA_RESTART;\r
+\r
+    if (sigaction(SIGPIPE, &sa, NULL) < 0) {\r
+        return -1;\r
+    }\r
+\r
+    memset(&sa, 0, sizeof (sa));\r
+    sa.sa_handler = term_handler;\r
+    sa.sa_flags = SA_RESTART;\r
+\r
+    if (sigaction(SIGHUP, &sa, NULL) < 0) {\r
+        return -1;\r
+    }\r
+    if (sigaction(SIGINT, &sa, NULL) < 0) {\r
+        return -1;\r
+    }\r
+    if (sigaction(SIGQUIT, &sa, NULL) < 0) {\r
+        return -1;\r
+    }\r
+    if (sigaction(SIGTERM, &sa, NULL) < 0) {\r
+        return -1;\r
+    }\r
+    return 0;\r
+}\r
+\r
+static void usage(char* whoami)\r
+{\r
+    fprintf(stderr, "usage: %s [-fcdt]\n", whoami);\r
+    fprintf(stderr, "  -c\tconfig file to use.\n");\r
+    fprintf(stderr, "  -d\tschema directory to use.\n");\r
+    fprintf(stderr, "  -t\tcheck configuration file for problems.\n");\r
+    fprintf(stderr, "  -f\tforce removal of listener socket.\n");\r
+    fprintf(stderr, "  -p\tpid file to use.\n");\r
+    fprintf(stderr, "  -h\tprint this help message.\n");\r
+    exit(1);\r
+}\r
+\r
+static int parse_args(int argc, char* argv[])\r
+{\r
+    int opt;\r
+\r
+    while ((opt = getopt(argc, argv, "c:d:p:fth")) > 0) {\r
+        switch (opt) {\r
+            case 'c':\r
+                shar_config=optarg;\r
+                break;\r
+            case 'd':\r
+                shar_schemadir=optarg;\r
+                break;\r
+            case 'f':\r
+                unlink_socket = 1;\r
+                break;\r
+            case 't':\r
+                shar_checkonly=true;\r
+                break;\r
+            case 'p':\r
+                pidfile=optarg;\r
+                break;\r
+            default:\r
+                return -1;\r
+        }\r
+    }\r
+    return 0;\r
+}\r
+\r
+int main(int argc, char *argv[])\r
+{\r
+    if (setup_signals() != 0)\r
+        return -1;\r
+\r
+    if (parse_args(argc, argv) != 0)\r
+        usage(argv[0]);\r
+\r
+    if (!shar_config)\r
+        shar_config=getenv("SHIBCONFIG");\r
+    if (!shar_schemadir)\r
+        shar_schemadir=getenv("SHIBSCHEMAS");\r
+    if (!shar_schemadir)\r
+        shar_schemadir=SHIBSP_SCHEMAS;\r
+    if (!shar_config)\r
+        shar_config=SHIBSP_CONFIG;\r
+\r
+    // initialize the shib-target library\r
+    SPConfig& conf=SPConfig::getConfig();\r
+    conf.setFeatures(\r
+        SPConfig::Listener |\r
+        SPConfig::Caching |\r
+        SPConfig::Metadata |\r
+        SPConfig::Trust |\r
+        SPConfig::Credentials |\r
+        SPConfig::AttributeResolver |\r
+        SPConfig::OutOfProcess |\r
+        (shar_checkonly ? (SPConfig::InProcess | SPConfig::RequestMapping) : SPConfig::Logging)\r
+        );\r
+    if (!conf.init(shar_schemadir)) {\r
+        fprintf(stderr, "configuration is invalid, check console for specific problems\n");\r
+        return -1;\r
+    }\r
+\r
+    try {\r
+        fprintf(stderr, "loading configuration file: %s\n", shar_config);\r
+        static const XMLCh path[] = UNICODE_LITERAL_4(p,a,t,h);\r
+        static const XMLCh validate[] = UNICODE_LITERAL_8(v,a,l,i,d,a,t,e);\r
+        DOMDocument* dummydoc=XMLToolingConfig::getConfig().getParser().newDocument();\r
+        XercesJanitor<DOMDocument> docjanitor(dummydoc);\r
+        DOMElement* dummy = dummydoc->createElementNS(NULL,path);\r
+        auto_ptr_XMLCh src(shar_config);\r
+        dummy->setAttributeNS(NULL,path,src.get());\r
+        dummy->setAttributeNS(NULL,validate,xmlconstants::XML_ONE);\r
+\r
+        conf.setServiceProvider(conf.ServiceProviderManager.newPlugin(XML_SERVICE_PROVIDER,dummy));\r
+        conf.getServiceProvider()->init();\r
+    }\r
+    catch (exception& ex) {\r
+        fprintf(stderr, "caught exception while loading configuration: %s\n", ex.what());\r
+        conf.term();\r
+        return -2;\r
+    }\r
+\r
+    if (shar_checkonly)\r
+        fprintf(stderr, "overall configuration is loadable, check console for non-fatal problems\n");\r
+    else {\r
+\r
+        // Write the pid file\r
+        if (pidfile) {\r
+            FILE* pidf = fopen(pidfile, "w");\r
+            if (pidf) {\r
+                fprintf(pidf, "%d\n", getpid());\r
+                fclose(pidf);\r
+            } else {\r
+                perror(pidfile);  // keep running though\r
+            }\r
+        }\r
+    \r
+        // Run the listener\r
+        if (!conf.getServiceProvider()->getListenerService()->run(&shibd_shutdown)) {\r
+            fprintf(stderr, "listener failed to enter listen loop\n");\r
+            return -3;\r
+        }\r
+    }\r
+\r
+    conf.term();\r
+    if (pidfile)\r
+        unlink(pidfile);\r
+    return 0;\r
+}\r
+\r
+#endif\r