--- /dev/null
+/*\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