time.c revision 1.1.1.2
168651Skris/*	$NetBSD: time.c,v 1.1.1.2 2010/03/08 02:14:20 lukem Exp $	*/
268651Skris
368651Skris/* time.c - deal with time subsystem */
468651Skris/* OpenLDAP: pkg/ldap/servers/slapd/back-monitor/time.c,v 1.37.2.4 2009/01/22 00:01:08 kurt Exp */
568651Skris/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
668651Skris *
768651Skris * Copyright 2001-2009 The OpenLDAP Foundation.
868651Skris * Portions Copyright 2001-2003 Pierangelo Masarati.
968651Skris * All rights reserved.
1068651Skris *
11267256Sjkim * Redistribution and use in source and binary forms, with or without
1268651Skris * modification, are permitted only as authorized by the OpenLDAP
1368651Skris * Public License.
1468651Skris *
15267256Sjkim * A copy of this license is available in file LICENSE in the
1668651Skris * top-level directory of the distribution or, alternatively, at
1768651Skris * <http://www.OpenLDAP.org/license.html>.
1876866Skris */
1968651Skris/* ACKNOWLEDGEMENTS:
2068651Skris * This work was initially developed by Pierangelo Masarati for inclusion
2168651Skris * in OpenLDAP Software.
2268651Skris */
2368651Skris
2468651Skris#include "portable.h"
2568651Skris
2668651Skris#include <stdio.h>
27267256Sjkim#include <ac/string.h>
2868651Skris#include <ac/time.h>
2968651Skris
3068651Skris
3168651Skris#include "slap.h"
3268651Skris#include <lutil.h>
3368651Skris#include "proto-slap.h"
3468651Skris#include "back-monitor.h"
3568651Skris
3668651Skrisstatic int
3768651Skrismonitor_subsys_time_update(
3868651Skris	Operation		*op,
3968651Skris	SlapReply		*rs,
4068651Skris	Entry                   *e );
4168651Skris
42267256Sjkimint
4368651Skrismonitor_subsys_time_init(
4468651Skris	BackendDB		*be,
4568651Skris	monitor_subsys_t	*ms )
4668651Skris{
4768651Skris	monitor_info_t	*mi;
4868651Skris
4968651Skris	Entry		*e, **ep, *e_time;
5068651Skris	monitor_entry_t	*mp;
5168651Skris	struct berval	bv, value;
5268651Skris
53	assert( be != NULL );
54
55	ms->mss_update = monitor_subsys_time_update;
56
57	mi = ( monitor_info_t * )be->be_private;
58
59	if ( monitor_cache_get( mi,
60			&ms->mss_ndn, &e_time ) ) {
61		Debug( LDAP_DEBUG_ANY,
62			"monitor_subsys_time_init: "
63			"unable to get entry \"%s\"\n",
64			ms->mss_ndn.bv_val, 0, 0 );
65		return( -1 );
66	}
67
68	mp = ( monitor_entry_t * )e_time->e_private;
69	mp->mp_children = NULL;
70	ep = &mp->mp_children;
71
72	BER_BVSTR( &bv, "cn=Start" );
73	e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
74		mi->mi_oc_monitoredObject, mi, NULL, NULL );
75	if ( e == NULL ) {
76		Debug( LDAP_DEBUG_ANY,
77			"monitor_subsys_time_init: "
78			"unable to create entry \"%s,%s\"\n",
79			bv.bv_val, ms->mss_ndn.bv_val, 0 );
80		return( -1 );
81	}
82	attr_merge_normalize_one( e, mi->mi_ad_monitorTimestamp,
83		&mi->mi_startTime, NULL );
84
85	mp = monitor_entrypriv_create();
86	if ( mp == NULL ) {
87		return -1;
88	}
89	e->e_private = ( void * )mp;
90	mp->mp_info = ms;
91	mp->mp_flags = ms->mss_flags \
92		| MONITOR_F_SUB | MONITOR_F_PERSISTENT;
93
94	if ( monitor_cache_add( mi, e ) ) {
95		Debug( LDAP_DEBUG_ANY,
96			"monitor_subsys_time_init: "
97			"unable to add entry \"%s,%s\"\n",
98			bv.bv_val, ms->mss_ndn.bv_val, 0 );
99		return( -1 );
100	}
101
102	*ep = e;
103	ep = &mp->mp_next;
104
105	/*
106	 * Current
107	 */
108	BER_BVSTR( &bv, "cn=Current" );
109	e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
110		mi->mi_oc_monitoredObject, mi, NULL, NULL );
111	if ( e == NULL ) {
112		Debug( LDAP_DEBUG_ANY,
113			"monitor_subsys_time_init: "
114			"unable to create entry \"%s,%s\"\n",
115			bv.bv_val, ms->mss_ndn.bv_val, 0 );
116		return( -1 );
117	}
118	attr_merge_normalize_one( e, mi->mi_ad_monitorTimestamp,
119		&mi->mi_startTime, NULL );
120
121	mp = monitor_entrypriv_create();
122	if ( mp == NULL ) {
123		return -1;
124	}
125	e->e_private = ( void * )mp;
126	mp->mp_info = ms;
127	mp->mp_flags = ms->mss_flags \
128		| MONITOR_F_SUB | MONITOR_F_PERSISTENT;
129
130	if ( monitor_cache_add( mi, e ) ) {
131		Debug( LDAP_DEBUG_ANY,
132			"monitor_subsys_time_init: "
133			"unable to add entry \"%s,%s\"\n",
134			bv.bv_val, ms->mss_ndn.bv_val, 0 );
135		return( -1 );
136	}
137
138	*ep = e;
139	ep = &mp->mp_next;
140
141	/*
142	 * Uptime
143	 */
144	BER_BVSTR( &bv, "cn=Uptime" );
145	e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
146		mi->mi_oc_monitoredObject, mi, NULL, NULL );
147	if ( e == NULL ) {
148		Debug( LDAP_DEBUG_ANY,
149			"monitor_subsys_time_init: "
150			"unable to create entry \"%s,%s\"\n",
151			bv.bv_val, ms->mss_ndn.bv_val, 0 );
152		return( -1 );
153	}
154	BER_BVSTR( &value, "0" );
155	attr_merge_normalize_one( e, mi->mi_ad_monitoredInfo,
156		&value, NULL );
157
158	mp = monitor_entrypriv_create();
159	if ( mp == NULL ) {
160		return -1;
161	}
162	e->e_private = ( void * )mp;
163	mp->mp_info = ms;
164	mp->mp_flags = ms->mss_flags \
165		| MONITOR_F_SUB | MONITOR_F_PERSISTENT;
166
167	if ( monitor_cache_add( mi, e ) ) {
168		Debug( LDAP_DEBUG_ANY,
169			"monitor_subsys_time_init: "
170			"unable to add entry \"%s,%s\"\n",
171			bv.bv_val, ms->mss_ndn.bv_val, 0 );
172		return( -1 );
173	}
174
175	*ep = e;
176	ep = &mp->mp_next;
177
178	monitor_cache_release( mi, e_time );
179
180	return( 0 );
181}
182
183static int
184monitor_subsys_time_update(
185	Operation		*op,
186	SlapReply		*rs,
187	Entry                   *e )
188{
189	monitor_info_t		*mi = ( monitor_info_t * )op->o_bd->be_private;
190	static struct berval	bv_current = BER_BVC( "cn=current" ),
191				bv_uptime = BER_BVC( "cn=uptime" );
192	struct berval		rdn;
193
194	assert( mi != NULL );
195	assert( e != NULL );
196
197	dnRdn( &e->e_nname, &rdn );
198
199	if ( dn_match( &rdn, &bv_current ) ) {
200		struct tm	*tm;
201#ifdef HAVE_GMTIME_R
202		struct tm	tm_buf;
203#endif
204		char		tmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
205		Attribute	*a;
206		ber_len_t	len;
207		time_t		currtime;
208
209		currtime = slap_get_time();
210
211#ifndef HAVE_GMTIME_R
212		ldap_pvt_thread_mutex_lock( &gmtime_mutex );
213#endif
214#ifdef HACK_LOCAL_TIME
215# ifdef HAVE_LOCALTIME_R
216		tm = localtime_r( &currtime, &tm_buf );
217# else
218		tm = localtime( &currtime );
219# endif /* HAVE_LOCALTIME_R */
220		lutil_localtime( tmbuf, sizeof( tmbuf ), tm, -timezone );
221#else /* !HACK_LOCAL_TIME */
222# ifdef HAVE_GMTIME_R
223		tm = gmtime_r( &currtime, &tm_buf );
224# else
225		tm = gmtime( &currtime );
226# endif /* HAVE_GMTIME_R */
227		lutil_gentime( tmbuf, sizeof( tmbuf ), tm );
228#endif /* !HACK_LOCAL_TIME */
229#ifndef HAVE_GMTIME_R
230		ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
231#endif
232
233		len = strlen( tmbuf );
234
235		a = attr_find( e->e_attrs, mi->mi_ad_monitorTimestamp );
236		if ( a == NULL ) {
237			return rs->sr_err = LDAP_OTHER;
238		}
239
240		assert( len == a->a_vals[ 0 ].bv_len );
241		AC_MEMCPY( a->a_vals[ 0 ].bv_val, tmbuf, len );
242
243		/* FIXME: touch modifyTimestamp? */
244
245	} else if ( dn_match( &rdn, &bv_uptime ) ) {
246		Attribute	*a;
247		double		diff;
248		char		buf[ BACKMONITOR_BUFSIZE ];
249		struct berval	bv;
250
251		a = attr_find( e->e_attrs, mi->mi_ad_monitoredInfo );
252		if ( a == NULL ) {
253			return rs->sr_err = LDAP_OTHER;
254		}
255
256		diff = difftime( slap_get_time(), starttime );
257		bv.bv_len = snprintf( buf, sizeof( buf ), "%lu",
258			(unsigned long) diff );
259		bv.bv_val = buf;
260
261		ber_bvreplace( &a->a_vals[ 0 ], &bv );
262		if ( a->a_nvals != a->a_vals ) {
263			ber_bvreplace( &a->a_nvals[ 0 ], &bv );
264		}
265
266		/* FIXME: touch modifyTimestamp? */
267	}
268
269	return SLAP_CB_CONTINUE;
270}
271
272