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