time.c revision 1.2
1/*	$NetBSD: time.c,v 1.2 2020/08/11 13:15:41 christos Exp $	*/
2
3/* time.c - deal with time subsystem */
4/* $OpenLDAP$ */
5/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
6 *
7 * Copyright 2001-2020 The OpenLDAP Foundation.
8 * Portions Copyright 2001-2003 Pierangelo Masarati.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted only as authorized by the OpenLDAP
13 * Public License.
14 *
15 * A copy of this license is available in file LICENSE in the
16 * top-level directory of the distribution or, alternatively, at
17 * <http://www.OpenLDAP.org/license.html>.
18 */
19/* ACKNOWLEDGEMENTS:
20 * This work was initially developed by Pierangelo Masarati for inclusion
21 * in OpenLDAP Software.
22 */
23
24#include <sys/cdefs.h>
25__RCSID("$NetBSD: time.c,v 1.2 2020/08/11 13:15:41 christos Exp $");
26
27#include "portable.h"
28
29#include <stdio.h>
30#include <ac/string.h>
31#include <ac/time.h>
32
33
34#include "slap.h"
35#include <lutil.h>
36#include "proto-slap.h"
37#include "back-monitor.h"
38
39static int
40monitor_subsys_time_update(
41	Operation		*op,
42	SlapReply		*rs,
43	Entry                   *e );
44
45int
46monitor_subsys_time_init(
47	BackendDB		*be,
48	monitor_subsys_t	*ms )
49{
50	monitor_info_t	*mi;
51
52	Entry		*e, **ep, *e_time;
53	monitor_entry_t	*mp;
54	struct berval	bv, value;
55
56	assert( be != NULL );
57
58	ms->mss_update = monitor_subsys_time_update;
59
60	mi = ( monitor_info_t * )be->be_private;
61
62	if ( monitor_cache_get( mi,
63			&ms->mss_ndn, &e_time ) ) {
64		Debug( LDAP_DEBUG_ANY,
65			"monitor_subsys_time_init: "
66			"unable to get entry \"%s\"\n",
67			ms->mss_ndn.bv_val, 0, 0 );
68		return( -1 );
69	}
70
71	mp = ( monitor_entry_t * )e_time->e_private;
72	mp->mp_children = NULL;
73	ep = &mp->mp_children;
74
75	BER_BVSTR( &bv, "cn=Start" );
76	e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
77		mi->mi_oc_monitoredObject, NULL, NULL );
78	if ( e == NULL ) {
79		Debug( LDAP_DEBUG_ANY,
80			"monitor_subsys_time_init: "
81			"unable to create entry \"%s,%s\"\n",
82			bv.bv_val, ms->mss_ndn.bv_val, 0 );
83		return( -1 );
84	}
85	attr_merge_normalize_one( e, mi->mi_ad_monitorTimestamp,
86		&mi->mi_startTime, NULL );
87
88	mp = monitor_entrypriv_create();
89	if ( mp == NULL ) {
90		return -1;
91	}
92	e->e_private = ( void * )mp;
93	mp->mp_info = ms;
94	mp->mp_flags = ms->mss_flags \
95		| MONITOR_F_SUB | MONITOR_F_PERSISTENT;
96
97	if ( monitor_cache_add( mi, e ) ) {
98		Debug( LDAP_DEBUG_ANY,
99			"monitor_subsys_time_init: "
100			"unable to add entry \"%s,%s\"\n",
101			bv.bv_val, ms->mss_ndn.bv_val, 0 );
102		return( -1 );
103	}
104
105	*ep = e;
106	ep = &mp->mp_next;
107
108	/*
109	 * Current
110	 */
111	BER_BVSTR( &bv, "cn=Current" );
112	e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
113		mi->mi_oc_monitoredObject, NULL, NULL );
114	if ( e == NULL ) {
115		Debug( LDAP_DEBUG_ANY,
116			"monitor_subsys_time_init: "
117			"unable to create entry \"%s,%s\"\n",
118			bv.bv_val, ms->mss_ndn.bv_val, 0 );
119		return( -1 );
120	}
121	attr_merge_normalize_one( e, mi->mi_ad_monitorTimestamp,
122		&mi->mi_startTime, NULL );
123
124	mp = monitor_entrypriv_create();
125	if ( mp == NULL ) {
126		return -1;
127	}
128	e->e_private = ( void * )mp;
129	mp->mp_info = ms;
130	mp->mp_flags = ms->mss_flags \
131		| MONITOR_F_SUB | MONITOR_F_PERSISTENT;
132
133	if ( monitor_cache_add( mi, e ) ) {
134		Debug( LDAP_DEBUG_ANY,
135			"monitor_subsys_time_init: "
136			"unable to add entry \"%s,%s\"\n",
137			bv.bv_val, ms->mss_ndn.bv_val, 0 );
138		return( -1 );
139	}
140
141	*ep = e;
142	ep = &mp->mp_next;
143
144	/*
145	 * Uptime
146	 */
147	BER_BVSTR( &bv, "cn=Uptime" );
148	e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
149		mi->mi_oc_monitoredObject, NULL, NULL );
150	if ( e == NULL ) {
151		Debug( LDAP_DEBUG_ANY,
152			"monitor_subsys_time_init: "
153			"unable to create entry \"%s,%s\"\n",
154			bv.bv_val, ms->mss_ndn.bv_val, 0 );
155		return( -1 );
156	}
157	BER_BVSTR( &value, "0" );
158	attr_merge_normalize_one( e, mi->mi_ad_monitoredInfo,
159		&value, NULL );
160
161	mp = monitor_entrypriv_create();
162	if ( mp == NULL ) {
163		return -1;
164	}
165	e->e_private = ( void * )mp;
166	mp->mp_info = ms;
167	mp->mp_flags = ms->mss_flags \
168		| MONITOR_F_SUB | MONITOR_F_PERSISTENT;
169
170	if ( monitor_cache_add( mi, e ) ) {
171		Debug( LDAP_DEBUG_ANY,
172			"monitor_subsys_time_init: "
173			"unable to add entry \"%s,%s\"\n",
174			bv.bv_val, ms->mss_ndn.bv_val, 0 );
175		return( -1 );
176	}
177
178	*ep = e;
179	ep = &mp->mp_next;
180
181	monitor_cache_release( mi, e_time );
182
183	return( 0 );
184}
185
186static int
187monitor_subsys_time_update(
188	Operation		*op,
189	SlapReply		*rs,
190	Entry                   *e )
191{
192	monitor_info_t		*mi = ( monitor_info_t * )op->o_bd->be_private;
193	static struct berval	bv_current = BER_BVC( "cn=current" ),
194				bv_uptime = BER_BVC( "cn=uptime" );
195	struct berval		rdn;
196
197	assert( mi != NULL );
198	assert( e != NULL );
199
200	dnRdn( &e->e_nname, &rdn );
201
202	if ( dn_match( &rdn, &bv_current ) ) {
203		struct tm	tm;
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		ldap_pvt_gmtime( &currtime, &tm );
212		lutil_gentime( tmbuf, sizeof( tmbuf ), &tm );
213
214		len = strlen( tmbuf );
215
216		a = attr_find( e->e_attrs, mi->mi_ad_monitorTimestamp );
217		if ( a == NULL ) {
218			return rs->sr_err = LDAP_OTHER;
219		}
220
221		assert( len == a->a_vals[ 0 ].bv_len );
222		AC_MEMCPY( a->a_vals[ 0 ].bv_val, tmbuf, len );
223
224		/* FIXME: touch modifyTimestamp? */
225
226	} else if ( dn_match( &rdn, &bv_uptime ) ) {
227		Attribute	*a;
228		double		diff;
229		char		buf[ BACKMONITOR_BUFSIZE ];
230		struct berval	bv;
231
232		a = attr_find( e->e_attrs, mi->mi_ad_monitoredInfo );
233		if ( a == NULL ) {
234			return rs->sr_err = LDAP_OTHER;
235		}
236
237		diff = difftime( slap_get_time(), starttime );
238		bv.bv_len = snprintf( buf, sizeof( buf ), "%lu",
239			(unsigned long) diff );
240		bv.bv_val = buf;
241
242		ber_bvreplace( &a->a_vals[ 0 ], &bv );
243		if ( a->a_nvals != a->a_vals ) {
244			ber_bvreplace( &a->a_nvals[ 0 ], &bv );
245		}
246
247		/* FIXME: touch modifyTimestamp? */
248	}
249
250	return SLAP_CB_CONTINUE;
251}
252
253