]> git.evergreen-ils.org Git - OpenSRF.git/blob - src/router/osrf_router_main.c
db4a29988ba6988fc3331b06fc2d8be7e8576a18
[OpenSRF.git] / src / router / osrf_router_main.c
1 #include "osrf_router.h"
2 #include <opensrf/osrfConfig.h>
3 #include <opensrf/utils.h>
4 #include <opensrf/log.h>
5 #include <opensrf/osrf_json.h>
6 #include <signal.h>
7
8 static osrfRouter* router = NULL;
9
10 void routerSignalHandler( int signo ) {
11         osrfLogWarning( OSRF_LOG_MARK, "Received signal [%d], cleaning up...", signo );
12
13     /* for now, just forcibly exit.  This is not a friendly way to clean up, but
14      * there is a bug in osrfRouterFree() (in particular with cleaning up sockets),
15      * that can cause the router process to stick around.  If we do this, we 
16      * are guaranteed to exit.  
17      */
18     _exit(0);
19
20         osrfConfigCleanup();
21         osrfRouterFree(router);
22         router = NULL;
23
24         // Exit by re-raising the signal so that the parent
25         // process can detect it
26         
27         signal( signo, SIG_DFL );
28         raise( signo );
29 }
30
31 static int setupRouter(jsonObject* configChunk);
32
33
34 int main( int argc, char* argv[] ) {
35
36         if( argc < 3 ) {
37                 osrfLogError( OSRF_LOG_MARK,
38                         "Usage: %s <path_to_config_file> <config_context>", argv[0] );
39                 exit( EXIT_FAILURE );
40         }
41
42         const char* config_file = argv[1];
43         const char* context = argv[2];
44
45         /* Get a set of router definitions from a config file */
46         
47         osrfConfig* cfg = osrfConfigInit(config_file, context);
48         if( NULL == cfg ) {
49                 osrfLogError( OSRF_LOG_MARK, "Router can't load config file %s", config_file );
50                 exit( EXIT_FAILURE );
51         }
52         
53         osrfConfigSetDefaultConfig(cfg);
54     jsonObject* configInfo = osrfConfigGetValueObject(NULL, "/router");
55         
56         if( configInfo->size < 1 || NULL == jsonObjectGetIndex( configInfo, 1 ) ) {
57                 osrfLogError( OSRF_LOG_MARK, "No routers defined in config file %s, context \"%s\"",
58                         config_file, context );
59                 exit( EXIT_FAILURE );
60         }
61         
62         /* We're done with the command line now, */
63         /* so we can safely overlay it */
64         
65         init_proc_title( argc, argv );
66         set_proc_title( "OpenSRF Router" );
67
68         /* Spawn child process(es) */
69         
70     int i;
71     for(i = 0; i < configInfo->size; i++) {
72         jsonObject* configChunk = jsonObjectGetIndex(configInfo, i);
73         if(fork() == 0) { /* create a new child to run this router instance */
74             setupRouter(configChunk);
75                         break;  /* We're a child; don't spawn any more children here */
76                 }
77     }
78
79         return EXIT_SUCCESS;
80 }
81
82 int setupRouter(jsonObject* configChunk) {
83
84     if(!jsonObjectGetKey(configChunk, "transport"))
85         return 0; /* these are not the configs you're looking for */
86
87         const char* server   = jsonObjectGetString(jsonObjectFindPath(configChunk, "/transport/server"));
88         const char* port     = jsonObjectGetString(jsonObjectFindPath(configChunk, "/transport/port"));
89         const char* username = jsonObjectGetString(jsonObjectFindPath(configChunk, "/transport/username"));
90         const char* password = jsonObjectGetString(jsonObjectFindPath(configChunk, "/transport/password"));
91         const char* resource = jsonObjectGetString(jsonObjectFindPath(configChunk, "/transport/resource"));
92
93         const char* level    = jsonObjectGetString(jsonObjectFindPath(configChunk, "/loglevel"));
94         const char* log_file = jsonObjectGetString(jsonObjectFindPath(configChunk, "/logfile"));
95         const char* facility = jsonObjectGetString(jsonObjectFindPath(configChunk, "/syslog"));
96
97         int llevel = 1;
98         if(level) llevel = atoi(level);
99
100         if(!log_file) { fprintf(stderr, "Log file name not specified\n"); return -1; }
101
102         if(!strcmp(log_file, "syslog")) {
103                 osrfLogInit( OSRF_LOG_TYPE_SYSLOG, "router", llevel );
104                 osrfLogSetSyslogFacility(osrfLogFacilityToInt(facility));
105
106         } else {
107                 osrfLogInit( OSRF_LOG_TYPE_FILE, "router", llevel );
108                 osrfLogSetFile( log_file );
109         }
110
111         osrfLogInfo(  OSRF_LOG_MARK, "Router connecting as: server: %s port: %s "
112                         "user: %s resource: %s", server, port, username, resource );
113
114         int iport = 0;
115         if(port)        iport = atoi( port );
116
117         osrfStringArray* tclients = osrfNewStringArray(4);
118         osrfStringArray* tservers = osrfNewStringArray(4);
119
120     jsonObject* tclientsList = jsonObjectFindPath(configChunk, "/trusted_domains/client");
121     jsonObject* tserversList = jsonObjectFindPath(configChunk, "/trusted_domains/server");
122
123         int i;
124
125     if(tserversList->type == JSON_ARRAY) {
126             for( i = 0; i != tserversList->size; i++ ) {
127             const char* serverDomain = jsonObjectGetString(jsonObjectGetIndex(tserversList, i));
128                     osrfLogInfo( OSRF_LOG_MARK,  "Router adding trusted server: %s", serverDomain);
129             osrfStringArrayAdd(tservers, serverDomain);
130         }
131     } else {
132         const char* serverDomain = jsonObjectGetString(tserversList);
133         osrfLogInfo( OSRF_LOG_MARK,  "Router adding trusted server: %s", serverDomain);
134         osrfStringArrayAdd(tservers, serverDomain);
135     }
136
137     if(tclientsList->type == JSON_ARRAY) {
138             for( i = 0; i != tclientsList->size; i++ ) {
139             const char* clientDomain = jsonObjectGetString(jsonObjectGetIndex(tclientsList, i));
140                     osrfLogInfo( OSRF_LOG_MARK,  "Router adding trusted client: %s", clientDomain);
141             osrfStringArrayAdd(tclients, clientDomain);
142         }
143     } else {
144         const char* clientDomain = jsonObjectGetString(tclientsList);
145         osrfLogInfo( OSRF_LOG_MARK,  "Router adding trusted client: %s", clientDomain);
146         osrfStringArrayAdd(tclients, clientDomain);
147     }
148
149
150         if( tclients->size == 0 || tservers->size == 0 ) {
151                 osrfLogError( OSRF_LOG_MARK, "We need trusted servers and trusted client to run the router...");
152                 osrfStringArrayFree( tservers );
153                 osrfStringArrayFree( tclients );
154                 return -1;
155         }
156
157         router = osrfNewRouter( server,
158                         username, resource, password, iport, tclients, tservers );
159         
160         signal(SIGHUP,routerSignalHandler);
161         signal(SIGINT,routerSignalHandler);
162         signal(SIGTERM,routerSignalHandler);
163
164         if( (osrfRouterConnect(router)) != 0 ) {
165                 fprintf(stderr, "Unable to connect router to jabber server %s... exiting\n", server );
166                 osrfRouterFree(router);
167                 return -1;
168         }
169
170         daemonize();
171         osrfRouterRun( router );
172
173         // Shouldn't get here, since osrfRouterRun()
174         // should go into an infinite loop
175
176         osrfRouterFree(router);
177         router = NULL;
178         
179         return -1;
180 }
181
182