]> git.sur5r.net Git - openldap/blob - servers/slurpd/main.c
3220853fb7f0d97fb46ab51e0b37e29fa6deb1e4
[openldap] / servers / slurpd / main.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6 /*
7  * Copyright (c) 1996 Regents of the University of Michigan.
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms are permitted
11  * provided that this notice is preserved and that due credit is given
12  * to the University of Michigan at Ann Arbor. The name of the University
13  * may not be used to endorse or promote products derived from this
14  * software without specific prior written permission. This software
15  * is provided ``as is'' without express or implied warranty.
16  */
17
18
19 /* 
20  * main.c - main routine for slurpd.
21  */
22
23 #include "portable.h"
24
25 #include <stdio.h>
26 #include <sys/stat.h>
27 #include <ac/stdlib.h>
28
29 #include "slurp.h"
30 #include "globals.h"
31 #include "lutil.h"
32
33 #include <ldap_pvt.h>
34
35 #ifdef HAVE_NT_SERVICE_MANAGER
36 #define MAIN_RETURN(x)  return
37 #define SERVICE_EXIT( e, n )    do { \
38         if ( is_NT_Service ) { \
39                 lutil_ServiceStatus.dwWin32ExitCode = (e); \
40                 lutil_ServiceStatus.dwServiceSpecificExitCode = (n); \
41         } \
42 } while ( 0 )
43 #else
44 #define SERVICE_EXIT( e, n )
45 #define MAIN_RETURN(x)  return(x)
46 #endif
47
48 #ifdef HAVE_NT_SERVICE_MANAGER
49 void WINAPI ServiceMain( DWORD argc, LPTSTR *argv )
50 #else
51 int main( int argc, char **argv )
52 #endif
53 {
54 #ifdef NO_THREADS
55     /* Haven't yet written the non-threaded version */
56     fputs( "slurpd currently requires threads support\n", stderr );
57     return( 1 );
58 #else
59
60     int                 i, rc = 0;
61
62     /* initialize thread package */
63     ldap_pvt_thread_initialize();
64
65     /* 
66      * Create and initialize globals.  init_globals() also initializes
67      * the main replication queue.
68      */
69     if (( sglob = init_globals()) == NULL ) {
70         fprintf( stderr, "Out of memory initializing globals\n" );
71         SERVICE_EXIT( ERROR_NOT_ENOUGH_MEMORY, 0 );
72         rc = 1;
73         goto stop;
74     }
75
76 #ifdef HAVE_NT_SERVICE_MANAGER
77         {
78                 int *i;
79                 char *newConfigFile;
80                 char *regService = NULL;
81
82                 if ( is_NT_Service ) {
83                         sglob->serverName = argv[0];
84                         lutil_CommenceStartupProcessing( sglob->serverName, slurp_set_shutdown );
85                         if ( strcmp(sglob->serverName, SERVICE_NAME) )
86                             regService = sglob->serverName;
87                 }
88
89                 i = (int*)lutil_getRegParam( regService, "DebugLevel" );
90                 if ( i != NULL ) 
91                 {
92                         ldap_debug = *i;
93 #ifdef NEW_LOGGING
94                         lutil_log_initialize( argc, argv );
95                         LDAP_LOG( SLURPD, INFO, 
96                                 "main: new debug level from registry is: %d\n", 
97                                 ldap_debug, 0, 0 );
98 #else
99                         Debug( LDAP_DEBUG_ANY, "new debug level from registry is: %d\n", ldap_debug, 0, 0 );
100 #endif
101                 }
102
103                 newConfigFile = (char*)lutil_getRegParam( regService, "ConfigFile" );
104                 if ( newConfigFile != NULL ) 
105                 {
106                         sglob->slapd_configfile = newConfigFile;
107 #ifdef NEW_LOGGING
108                         LDAP_LOG( SLURPD, INFO, 
109                                 "main: new config file from registry is: %s\n", sglob->slapd_configfile, 0, 0 );
110 #else
111                         Debug ( LDAP_DEBUG_ANY, "new config file from registry is: %s\n", sglob->slapd_configfile, 0, 0 );
112 #endif
113
114                 }
115         }
116 #endif
117
118     /*
119      * Process command-line args and fill in globals.
120      */
121     if ( doargs( argc, argv, sglob ) < 0 ) {
122         SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 15 );
123         rc = 1;
124         goto stop;
125     }
126
127     /*
128      * Read slapd config file and initialize Re (per-replica) structs.
129      */
130     if ( slurpd_read_config( sglob->slapd_configfile ) < 0 ) {
131         fprintf( stderr,
132                 "Errors encountered while processing config file \"%s\"\n",
133                 sglob->slapd_configfile );
134         SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 19 );
135         rc = 1;
136         goto stop;
137     }
138
139 #ifdef HAVE_TLS
140         if( ldap_pvt_tls_init() || ldap_pvt_tls_init_def_ctx() ) {
141                 fprintf( stderr, "TLS Initialization failed.\n" );
142                 SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 20 );
143                 rc = 1;
144                 goto stop;
145         }
146 #endif
147
148     /* 
149      * Make sure our directory exists
150      */
151     if ( mkdir(sglob->slurpd_rdir, 0755) == -1 && errno != EEXIST) {
152         perror(sglob->slurpd_rdir);
153         SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 16 );
154         rc = 1;
155         goto stop;
156     }
157
158     /*
159      * Get any saved state information off the disk.
160      */
161     if ( sglob->st->st_read( sglob->st )) {
162         fprintf( stderr, "Malformed slurpd status file \"%s\"\n",
163                 sglob->slurpd_status_file, 0, 0 );
164         SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 17 );
165         rc = 1;
166         goto stop;
167     }
168
169     /*
170      * All readonly data should now be initialized. 
171      * Check for any fatal error conditions before we get started
172      */
173      if ( sanity() < 0 ) {
174         SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 18 );
175         rc = 1;
176         goto stop;
177     }
178
179     /*
180      * Detach from the controlling terminal
181      * unless the -d flag is given or in one-shot mode.
182      */
183 #ifndef HAVE_WINSOCK
184     if ( ! (sglob->no_detach || sglob->one_shot_mode) )
185         lutil_detach( 0, 0 );
186 #endif
187
188 #ifdef HAVE_NT_EVENT_LOG
189         if (is_NT_Service) lutil_LogStartedEvent( sglob->serverName, ldap_debug, sglob->slapd_configfile, "n/a" );
190 #endif
191
192     /*
193      * Start the main file manager thread (in fm.c).
194      */
195     if ( ldap_pvt_thread_create( &(sglob->fm_tid),
196                 0, fm, (void *) NULL ) != 0 )
197         {
198 #ifdef NEW_LOGGING
199         LDAP_LOG ( SLURPD, ERR,
200                 "main: file manager ldap_pvt_thread_create failed\n" , 0, 0, 0 );
201 #else
202         Debug( LDAP_DEBUG_ANY, "file manager ldap_pvt_thread_create failed\n",
203                 0, 0, 0 );
204 #endif
205         SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 21 );
206         rc = 1;
207         goto stop;
208
209     }
210
211     /*
212      * wait for fm to finish if in oneshot mode
213      */
214     if ( sglob->one_shot_mode ) {
215         ldap_pvt_thread_join( sglob->fm_tid, (void *) NULL );
216     }
217
218     /*
219      * Start threads - one thread for each replica
220      */
221     for ( i = 0; sglob->replicas[ i ] != NULL; i++ ) {
222         start_replica_thread( sglob->replicas[ i ]);
223     }
224
225 #ifdef HAVE_NT_SERVICE_MANAGER
226     if ( started_event ) ldap_pvt_thread_cond_signal( &started_event );
227 #endif
228
229     /*
230      * Wait for the fm thread to finish.
231      */
232     if ( !sglob->one_shot_mode ) {
233         ldap_pvt_thread_join( sglob->fm_tid, (void *) NULL );
234     }
235
236     /*
237      * Wait for the replica threads to finish.
238      */
239     for ( i = 0; sglob->replicas[ i ] != NULL; i++ ) {
240         ldap_pvt_thread_join( sglob->replicas[ i ]->ri_tid, (void *) NULL );
241     }
242
243 stop:
244 #ifdef HAVE_NT_SERVICE_MANAGER
245         if (is_NT_Service) {
246                 ldap_pvt_thread_cond_destroy( &started_event );
247                 lutil_LogStoppedEvent( sglob->serverName );
248                 lutil_ReportShutdownComplete();
249         }
250 #endif
251     /* destroy the thread package */
252     ldap_pvt_thread_destroy();
253
254 #ifdef NEW_LOGGING
255         LDAP_LOG ( SLURPD, RESULTS, "main: slurpd terminated\n", 0, 0, 0 );
256 #else
257     Debug( LDAP_DEBUG_ANY, "slurpd: terminated.\n", 0, 0, 0 );
258 #endif
259         MAIN_RETURN(rc);
260 #endif /* !NO_THREADS */
261 }