2 * Copyright 2001-2007 Internet2
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * shar.cpp -- the shibd "main" code. All the functionality is elsewhere
20 * Created By: Derek Atkins <derek@ihtfp.com>
26 // eventually we might be able to support autoconf via cygwin...
27 #if defined (_MSC_VER) || defined(__BORLANDC__)
28 # include "config_win32.h"
34 # define _CRT_NONSTDC_NO_DEPRECATE 1
35 # define _CRT_SECURE_NO_DEPRECATE 1
38 #include <shibsp/SPConfig.h>
42 #include <sys/select.h>
47 #include <log4cpp/Category.hh>
48 #include <shibsp/ServiceProvider.h>
49 #include <shibsp/remoting/ListenerService.h>
50 #include <xercesc/util/XMLUniDefs.hpp>
51 #include <xmltooling/XMLToolingConfig.h>
52 #include <xmltooling/util/XMLHelper.h>
54 using namespace shibsp;
55 using namespace log4cpp;
56 using namespace xmltooling;
59 bool shibd_shutdown = false;
60 const char* shar_config = NULL;
61 const char* shar_schemadir = NULL;
62 bool shar_checkonly = false;
63 static int unlink_socket = 0;
64 const char* pidfile = NULL;
70 #define nNoMansLandSize 4
71 typedef struct _CrtMemBlockHeader
73 struct _CrtMemBlockHeader * pBlockHeaderNext;
74 struct _CrtMemBlockHeader * pBlockHeaderPrev;
80 unsigned char gap[nNoMansLandSize];
82 * unsigned char data[nDataSize];
83 * unsigned char anotherGap[nNoMansLandSize];
88 int MyAllocHook(int nAllocType, void *pvData,
89 size_t nSize, int nBlockUse, long lRequest,
90 const unsigned char * szFileName, int nLine)
92 if ( nBlockUse == _CRT_BLOCK )
94 if (nAllocType == _HOOK_FREE) {
95 _CrtMemBlockHeader* ptr = (_CrtMemBlockHeader*)(((_CrtMemBlockHeader *)pvData)-1);
96 if (ptr->nDataSize == 8192)
97 fprintf(stderr,"free request %u size %u\n", ptr->lRequest, ptr->nDataSize);
99 else if (nAllocType == _HOOK_ALLOC && nSize == 8192)
100 fprintf(stderr,"%s request %u size %u\n", ((nAllocType == _HOOK_ALLOC) ? "alloc" : "realloc"), lRequest, nSize);
105 int real_main(int preinit)
107 SPConfig& conf=SPConfig::getConfig();
110 // Initialize the SP library.
116 SPConfig::Credentials |
117 SPConfig::AttributeResolver |
118 SPConfig::OutOfProcess |
119 (shar_checkonly ? (SPConfig::InProcess | SPConfig::RequestMapping) : SPConfig::Logging)
122 shar_config=getenv("SHIBCONFIG");
124 shar_schemadir=getenv("SHIBSCHEMAS");
126 shar_schemadir=SHIBSP_SCHEMAS;
128 shar_config=SHIBSP_CONFIG;
129 if (!conf.init(shar_schemadir)) {
130 fprintf(stderr, "configuration is invalid, see console for specific problems\n");
135 fprintf(stderr, "loading configuration file: %s\n", shar_config);
136 static const XMLCh path[] = UNICODE_LITERAL_4(p,a,t,h);
137 DOMDocument* dummydoc=XMLToolingConfig::getConfig().getParser().newDocument();
138 XercesJanitor<DOMDocument> docjanitor(dummydoc);
139 DOMElement* dummy = dummydoc->createElementNS(NULL,path);
140 auto_ptr_XMLCh src(shar_config);
141 dummy->setAttributeNS(NULL,path,src.get());
143 conf.setServiceProvider(conf.ServiceProviderManager.newPlugin(XML_SERVICE_PROVIDER,dummy));
144 conf.getServiceProvider()->init();
146 catch (exception& ex) {
147 fprintf(stderr, "caught exception while loading configuration: %s\n", ex.what());
152 // If just a test run, bail.
153 if (shar_checkonly) {
154 fprintf(stdout, "overall configuration is loadable, check console for non-fatal problems\n");
160 //_CrtSetAllocHook(MyAllocHook);
163 if (!shar_checkonly) {
166 if (!conf.getServiceProvider()->getListenerService()->run(&shibd_shutdown)) {
167 fprintf(stderr, "listener failed to enter listen loop\n");
179 static void term_handler(int arg)
181 shibd_shutdown = true;
184 static int setup_signals(void)
187 memset(&sa, 0, sizeof (sa));
188 sa.sa_handler = SIG_IGN;
189 sa.sa_flags = SA_RESTART;
191 if (sigaction(SIGPIPE, &sa, NULL) < 0) {
195 memset(&sa, 0, sizeof (sa));
196 sa.sa_handler = term_handler;
197 sa.sa_flags = SA_RESTART;
199 if (sigaction(SIGHUP, &sa, NULL) < 0) {
202 if (sigaction(SIGINT, &sa, NULL) < 0) {
205 if (sigaction(SIGQUIT, &sa, NULL) < 0) {
208 if (sigaction(SIGTERM, &sa, NULL) < 0) {
214 static void usage(char* whoami)
216 fprintf(stderr, "usage: %s [-fcdt]\n", whoami);
217 fprintf(stderr, " -c\tconfig file to use.\n");
218 fprintf(stderr, " -d\tschema directory to use.\n");
219 fprintf(stderr, " -t\tcheck configuration file for problems.\n");
220 fprintf(stderr, " -f\tforce removal of listener socket.\n");
221 fprintf(stderr, " -p\tpid file to use.\n");
222 fprintf(stderr, " -h\tprint this help message.\n");
226 static int parse_args(int argc, char* argv[])
230 while ((opt = getopt(argc, argv, "c:d:p:fth")) > 0) {
236 shar_schemadir=optarg;
254 int main(int argc, char *argv[])
256 if (setup_signals() != 0)
259 if (parse_args(argc, argv) != 0)
263 shar_config=getenv("SHIBCONFIG");
265 shar_schemadir=getenv("SHIBSCHEMAS");
267 shar_schemadir=SHIBSP_SCHEMAS;
269 shar_config=SHIBSP_CONFIG;
271 // initialize the shib-target library
272 SPConfig& conf=SPConfig::getConfig();
278 SPConfig::Credentials |
279 SPConfig::AttributeResolver |
280 SPConfig::OutOfProcess |
281 (shar_checkonly ? (SPConfig::InProcess | SPConfig::RequestMapping) : SPConfig::Logging)
283 if (!conf.init(shar_schemadir)) {
284 fprintf(stderr, "configuration is invalid, check console for specific problems\n");
289 fprintf(stderr, "loading configuration file: %s\n", shar_config);
290 static const XMLCh path[] = UNICODE_LITERAL_4(p,a,t,h);
291 DOMDocument* dummydoc=XMLToolingConfig::getConfig().getParser().newDocument();
292 XercesJanitor<DOMDocument> docjanitor(dummydoc);
293 DOMElement* dummy = dummydoc->createElementNS(NULL,path);
294 auto_ptr_XMLCh src(shar_config);
295 dummy->setAttributeNS(NULL,path,src.get());
297 conf.setServiceProvider(conf.ServiceProviderManager.newPlugin(XML_SERVICE_PROVIDER,dummy));
298 conf.getServiceProvider()->init();
300 catch (exception& ex) {
301 fprintf(stderr, "caught exception while loading configuration: %s\n", ex.what());
307 fprintf(stderr, "overall configuration is loadable, check console for non-fatal problems\n");
310 // Write the pid file
312 FILE* pidf = fopen(pidfile, "w");
314 fprintf(pidf, "%d\n", getpid());
317 perror(pidfile); // keep running though
322 if (!conf.getServiceProvider()->getListenerService()->run(&shibd_shutdown)) {
323 fprintf(stderr, "listener failed to enter listen loop\n");