xref: /netbsd-src/external/bsd/openldap/dist/servers/slapd/back-monitor/time.c (revision 6a493d6bc668897c91594964a732d38505b70cbb)
1 /*	$NetBSD: time.c,v 1.1.1.3 2010/12/12 15:23:16 adam Exp $	*/
2 
3 /* time.c - deal with time subsystem */
4 /* OpenLDAP: pkg/ldap/servers/slapd/back-monitor/time.c,v 1.37.2.6 2010/04/19 16:53:03 quanah Exp */
5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
6  *
7  * Copyright 2001-2010 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 "portable.h"
25 
26 #include <stdio.h>
27 #include <ac/string.h>
28 #include <ac/time.h>
29 
30 
31 #include "slap.h"
32 #include <lutil.h>
33 #include "proto-slap.h"
34 #include "back-monitor.h"
35 
36 static int
37 monitor_subsys_time_update(
38 	Operation		*op,
39 	SlapReply		*rs,
40 	Entry                   *e );
41 
42 int
43 monitor_subsys_time_init(
44 	BackendDB		*be,
45 	monitor_subsys_t	*ms )
46 {
47 	monitor_info_t	*mi;
48 
49 	Entry		*e, **ep, *e_time;
50 	monitor_entry_t	*mp;
51 	struct berval	bv, value;
52 
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 
183 static int
184 monitor_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 		char		tmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
202 		Attribute	*a;
203 		ber_len_t	len;
204 		time_t		currtime;
205 
206 		currtime = slap_get_time();
207 
208 		ldap_pvt_gmtime( &currtime, &tm );
209 		lutil_gentime( tmbuf, sizeof( tmbuf ), &tm );
210 
211 		len = strlen( tmbuf );
212 
213 		a = attr_find( e->e_attrs, mi->mi_ad_monitorTimestamp );
214 		if ( a == NULL ) {
215 			return rs->sr_err = LDAP_OTHER;
216 		}
217 
218 		assert( len == a->a_vals[ 0 ].bv_len );
219 		AC_MEMCPY( a->a_vals[ 0 ].bv_val, tmbuf, len );
220 
221 		/* FIXME: touch modifyTimestamp? */
222 
223 	} else if ( dn_match( &rdn, &bv_uptime ) ) {
224 		Attribute	*a;
225 		double		diff;
226 		char		buf[ BACKMONITOR_BUFSIZE ];
227 		struct berval	bv;
228 
229 		a = attr_find( e->e_attrs, mi->mi_ad_monitoredInfo );
230 		if ( a == NULL ) {
231 			return rs->sr_err = LDAP_OTHER;
232 		}
233 
234 		diff = difftime( slap_get_time(), starttime );
235 		bv.bv_len = snprintf( buf, sizeof( buf ), "%lu",
236 			(unsigned long) diff );
237 		bv.bv_val = buf;
238 
239 		ber_bvreplace( &a->a_vals[ 0 ], &bv );
240 		if ( a->a_nvals != a->a_vals ) {
241 			ber_bvreplace( &a->a_nvals[ 0 ], &bv );
242 		}
243 
244 		/* FIXME: touch modifyTimestamp? */
245 	}
246 
247 	return SLAP_CB_CONTINUE;
248 }
249 
250