]> git.sur5r.net Git - openldap/blob - servers/slapd/back-monitor/time.c
Import ITS#2007 and ITS#2009 bug fixes from HEAD
[openldap] / servers / slapd / back-monitor / time.c
1 /* time.c - deal with time subsystem */
2 /*
3  * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6 /*
7  * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
8  * 
9  * This work has beed deveolped for the OpenLDAP Foundation 
10  * in the hope that it may be useful to the Open Source community, 
11  * but WITHOUT ANY WARRANTY.
12  * 
13  * Permission is granted to anyone to use this software for any purpose
14  * on any computer system, and to alter it and redistribute it, subject
15  * to the following restrictions:
16  * 
17  * 1. The author and SysNet s.n.c. are not responsible for the consequences
18  *    of use of this software, no matter how awful, even if they arise from
19  *    flaws in it.
20  * 
21  * 2. The origin of this software must not be misrepresented, either by
22  *    explicit claim or by omission.  Since few users ever read sources,
23  *    credits should appear in the documentation.
24  * 
25  * 3. Altered versions must be plainly marked as such, and must not be
26  *    misrepresented as being the original software.  Since few users
27  *    ever read sources, credits should appear in the documentation.
28  *    SysNet s.n.c. cannot be responsible for the consequences of the
29  *    alterations.
30  * 
31  * 4. This notice may not be removed or altered.
32  */
33
34 #include "portable.h"
35
36 #include <stdio.h>
37 #include <ac/string.h>
38 #include <ac/time.h>
39
40 #include "slap.h"
41 #include "proto-slap.h"
42 #include "back-monitor.h"
43
44 #ifdef HACK_LOCAL_TIME
45 static int
46 local_time( const struct tm *ztm, long delta, char *buf, size_t len );
47 #endif /* HACK_LOCAL_TIME */
48
49 int
50 monitor_subsys_time_init(
51         BackendDB               *be
52 )
53 {
54         struct monitorinfo      *mi;
55         
56         Entry                   *e, *e_tmp, *e_time;
57         struct monitorentrypriv *mp;
58         char                    buf[1024];
59         struct tm               *tms;
60         char                    tmbuf[20];
61
62         /*
63          * Note: ltmbuf, ltm are used only if HACK_LOCAL_TIME is defined
64          */
65
66         assert( be != NULL );
67
68         mi = ( struct monitorinfo * )be->be_private;
69
70         if ( monitor_cache_get( mi,
71                         &monitor_subsys[SLAPD_MONITOR_TIME].mss_ndn, &e_time ) ) {
72 #ifdef NEW_LOGGING
73                 LDAP_LOG( OPERATION, CRIT,
74                         "monitor_subsys_time_init: "
75                         "unable to get entry '%s'\n",
76                         monitor_subsys[SLAPD_MONITOR_TIME].mss_ndn.bv_val, 0, 0 );
77 #else
78                 Debug( LDAP_DEBUG_ANY,
79                         "monitor_subsys_time_init: "
80                         "unable to get entry '%s'\n%s%s",
81                         monitor_subsys[SLAPD_MONITOR_TIME].mss_ndn.bv_val, 
82                         "", "" );
83 #endif
84                 return( -1 );
85         }
86
87         e_tmp = NULL;
88
89         /*
90          * Start
91          */
92         ldap_pvt_thread_mutex_lock( &gmtime_mutex );
93 #ifdef HACK_LOCAL_TIME
94         tms = localtime( &starttime );
95         local_time( tms, -timezone, tmbuf, sizeof( tmbuf ) );
96 #else /* !HACK_LOCAL_TIME */
97         tms = gmtime( &starttime );
98         lutil_gentime( tmbuf, sizeof(tmbuf), tms );
99 #endif /* !HACK_LOCAL_TIME */
100         ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
101         snprintf( buf, sizeof( buf ),
102                         "dn: cn=Start,%s\n"
103                         SLAPD_MONITOR_OBJECTCLASSES
104                         "cn: Start\n"
105                         "createTimestamp: %s", 
106                         monitor_subsys[SLAPD_MONITOR_TIME].mss_dn.bv_val,
107                         tmbuf );
108
109         e = str2entry( buf );
110         if ( e == NULL ) {
111 #ifdef NEW_LOGGING
112                 LDAP_LOG( OPERATION, CRIT,
113                         "monitor_subsys_time_init: "
114                         "unable to create entry 'cn=Start,%s'\n",
115                         monitor_subsys[SLAPD_MONITOR_TIME].mss_ndn.bv_val, 0, 0 );
116 #else
117                 Debug( LDAP_DEBUG_ANY,
118                         "monitor_subsys_time_init: "
119                         "unable to create entry 'cn=Start,%s'\n%s%s",
120                         monitor_subsys[SLAPD_MONITOR_TIME].mss_ndn.bv_val,
121                         "", "" );
122 #endif
123                 return( -1 );
124         }
125         
126         mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
127         e->e_private = ( void * )mp;
128         mp->mp_next = e_tmp;
129         mp->mp_children = NULL;
130         mp->mp_info = &monitor_subsys[SLAPD_MONITOR_TIME];
131         mp->mp_flags = monitor_subsys[SLAPD_MONITOR_TIME].mss_flags \
132                 | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
133
134         if ( monitor_cache_add( mi, e ) ) {
135 #ifdef NEW_LOGGING
136                 LDAP_LOG( OPERATION, CRIT,
137                         "monitor_subsys_time_init: "
138                         "unable to add entry 'cn=Start,%s'\n",
139                         monitor_subsys[SLAPD_MONITOR_TIME].mss_ndn.bv_val, 0, 0 );
140 #else
141                 Debug( LDAP_DEBUG_ANY,
142                         "monitor_subsys_time_init: "
143                         "unable to add entry 'cn=Start,%s'\n%s%s",
144                         monitor_subsys[SLAPD_MONITOR_TIME].mss_ndn.bv_val,
145                         "", "" );
146 #endif
147                 return( -1 );
148         }
149         
150         e_tmp = e;
151
152         /*
153          * Current
154          */
155         snprintf( buf, sizeof( buf ),
156                         "dn: cn=Current,%s\n"
157                         SLAPD_MONITOR_OBJECTCLASSES
158                         "cn: Current\n"
159                         "createTimestamp: %s\n"
160                         "modifyTimestamp: %s",
161                         monitor_subsys[SLAPD_MONITOR_TIME].mss_dn.bv_val,
162                         tmbuf, tmbuf );
163
164         e = str2entry( buf );
165         if ( e == NULL ) {
166 #ifdef NEW_LOGGING
167                 LDAP_LOG( OPERATION, CRIT,
168                         "monitor_subsys_time_init: "
169                         "unable to create entry 'cn=Current,%s'\n",
170                         monitor_subsys[SLAPD_MONITOR_TIME].mss_ndn.bv_val, 0, 0 );
171 #else
172                 Debug( LDAP_DEBUG_ANY,
173                         "monitor_subsys_time_init: "
174                         "unable to create entry 'cn=Current,%s'\n%s%s",
175                         monitor_subsys[SLAPD_MONITOR_TIME].mss_ndn.bv_val,
176                         "", "" );
177 #endif
178                 return( -1 );
179         }
180         
181         mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
182         e->e_private = ( void * )mp;
183         mp->mp_next = e_tmp;
184         mp->mp_children = NULL;
185         mp->mp_info = &monitor_subsys[SLAPD_MONITOR_TIME];
186         mp->mp_flags = monitor_subsys[SLAPD_MONITOR_TIME].mss_flags \
187                 | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
188
189         if ( monitor_cache_add( mi, e ) ) {
190 #ifdef NEW_LOGGING
191                 LDAP_LOG( OPERATION, CRIT,
192                         "monitor_subsys_time_init: "
193                         "unable to add entry 'cn=Current,%s'\n",
194                         monitor_subsys[SLAPD_MONITOR_TIME].mss_ndn.bv_val, 0, 0 );
195 #else
196                 Debug( LDAP_DEBUG_ANY,
197                         "monitor_subsys_time_init: "
198                         "unable to add entry 'cn=Current,%s'\n%s%s",
199                         monitor_subsys[SLAPD_MONITOR_TIME].mss_ndn.bv_val,
200                         "", "" );
201 #endif
202                 return( -1 );
203         }
204         
205         e_tmp = e;
206
207         mp = ( struct monitorentrypriv * )e_time->e_private;
208         mp->mp_children = e_tmp;
209
210         monitor_cache_release( mi, e_time );
211
212         return( 0 );
213 }
214
215 int
216 monitor_subsys_time_update(
217         struct monitorinfo      *mi,
218         Entry                   *e
219 )
220 {
221         char            stmbuf[20], ctmbuf[20];
222         struct tm       *stm, *ctm;
223         Attribute       *a;
224         ber_len_t       len;
225
226         static int      init_start = 0, init_current = 0;
227 #define ENTRY_TIME      0
228 #define ENTRY_START     1
229 #define ENTRY_CURRENT   2
230         int             entry = ENTRY_TIME;
231
232         assert( mi );
233         assert( e );
234         
235         if ( strncmp( e->e_nname.bv_val, "cn=start", 
236                                 sizeof("cn=start")-1 ) == 0 ) {
237                 entry = ENTRY_START;
238                 if ( init_start == 1 ) {
239                         return( 0 );
240                 }
241
242         } else if ( strncmp( e->e_nname.bv_val, "cn=current",
243                                 sizeof("cn=current")-1 ) == 0 ) {
244                 entry = ENTRY_CURRENT;
245         }
246         
247         ldap_pvt_thread_mutex_lock( &gmtime_mutex );
248         if ( init_start == 0 ) {
249 #ifdef HACK_LOCAL_TIME
250                 stm = localtime( &starttime );
251                 local_time( stm, -timezone, stmbuf, sizeof( stmbuf ) );
252 #else /* !HACK_LOCAL_TIME */
253                 stm = gmtime( &starttime );
254                 lutil_gentime( stmbuf, sizeof( stmbuf ), stm );
255 #endif /* !HACK_LOCAL_TIME */
256         }
257
258         if ( entry == ENTRY_CURRENT ) {
259                 time_t currentTime = slap_get_time();
260 #ifdef HACK_LOCAL_TIME
261                 ctm = localtime( &currentTime );
262                 local_time( ctm, -timezone, ctmbuf, sizeof( ctmbuf ) );
263 #else /* !HACK_LOCAL_TIME */
264                 ctm = gmtime( &currentTime );
265                 lutil_gentime( ctmbuf, sizeof( ctmbuf ), ctm );
266 #endif /* !HACK_LOCAL_TIME */
267         }
268         ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
269
270         if ( ( entry == ENTRY_START && init_start == 0 ) 
271                         || ( entry == ENTRY_CURRENT && init_current == 0 ) ) {
272                 a = attr_find( e->e_attrs, slap_schema.si_ad_createTimestamp );
273                 if ( a == NULL ) {
274                         return( -1 );
275                 }
276
277                 len = strlen( stmbuf );
278                 assert( len == a->a_vals[0].bv_len );
279                 AC_MEMCPY( a->a_vals[0].bv_val, stmbuf, len );
280
281                 if ( entry == ENTRY_START ) {
282                         init_start = 1;
283                 } else if ( entry == ENTRY_CURRENT ) {
284                         init_current = 1;
285                 }
286         }
287
288         if ( entry == ENTRY_CURRENT ) {
289                 a = attr_find( e->e_attrs, slap_schema.si_ad_modifyTimestamp );
290                 if ( a == NULL ) {
291                         return( -1 );
292                 }
293
294                 len = strlen( ctmbuf );
295                 assert( len == a->a_vals[0].bv_len );
296                 AC_MEMCPY( a->a_vals[0].bv_val, ctmbuf, len );
297         }
298
299         return( 0 );
300 }
301
302 #ifdef HACK_LOCAL_TIME
303 /*
304  * assumes gmtime_mutex is locked
305  */
306 static int
307 local_time( const struct tm *ltm, long delta, char *buf, size_t len )
308 {
309         char *p;
310
311         if ( len < 20 ) {
312                 return -1;
313         }
314         strftime( buf, len, "%Y%m%d%H%M%S", ltm );
315
316         p = buf + 14;
317
318         if ( delta < 0 ) {
319                 p[ 0 ] = '-';
320                 delta = -delta;
321         } else {
322                 p[ 0 ] = '+';
323         }
324         p++;
325
326         snprintf( p, len - 15, "%02ld%02ld", delta / 3600, delta % 3600 );
327         
328         return 0;
329 }
330 #endif /* HACK_LOCAL_TIME */
331