1 /* $NetBSD: time.c,v 1.4 2025/09/05 21:16:29 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-2024 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.4 2025/09/05 21:16:29 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 39 static int 40 monitor_subsys_time_update( 41 Operation *op, 42 SlapReply *rs, 43 Entry *e ); 44 45 int 46 monitor_subsys_time_init( 47 BackendDB *be, 48 monitor_subsys_t *ms ) 49 { 50 monitor_info_t *mi; 51 52 Entry *e, *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 ); 68 return( -1 ); 69 } 70 71 BER_BVSTR( &bv, "cn=Start" ); 72 e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv, 73 mi->mi_oc_monitoredObject, NULL, NULL ); 74 if ( e == NULL ) { 75 Debug( LDAP_DEBUG_ANY, 76 "monitor_subsys_time_init: " 77 "unable to create entry \"%s,%s\"\n", 78 bv.bv_val, ms->mss_ndn.bv_val ); 79 return( -1 ); 80 } 81 attr_merge_normalize_one( e, mi->mi_ad_monitorTimestamp, 82 &mi->mi_startTime, NULL ); 83 84 mp = monitor_entrypriv_create(); 85 if ( mp == NULL ) { 86 return -1; 87 } 88 e->e_private = ( void * )mp; 89 mp->mp_info = ms; 90 mp->mp_flags = ms->mss_flags \ 91 | MONITOR_F_SUB | MONITOR_F_PERSISTENT; 92 93 if ( monitor_cache_add( mi, e, e_time ) ) { 94 Debug( LDAP_DEBUG_ANY, 95 "monitor_subsys_time_init: " 96 "unable to add entry \"%s,%s\"\n", 97 bv.bv_val, ms->mss_ndn.bv_val ); 98 return( -1 ); 99 } 100 101 /* 102 * Current 103 */ 104 BER_BVSTR( &bv, "cn=Current" ); 105 e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv, 106 mi->mi_oc_monitoredObject, NULL, NULL ); 107 if ( e == NULL ) { 108 Debug( LDAP_DEBUG_ANY, 109 "monitor_subsys_time_init: " 110 "unable to create entry \"%s,%s\"\n", 111 bv.bv_val, ms->mss_ndn.bv_val ); 112 return( -1 ); 113 } 114 attr_merge_normalize_one( e, mi->mi_ad_monitorTimestamp, 115 &mi->mi_startTime, NULL ); 116 117 mp = monitor_entrypriv_create(); 118 if ( mp == NULL ) { 119 return -1; 120 } 121 e->e_private = ( void * )mp; 122 mp->mp_info = ms; 123 mp->mp_flags = ms->mss_flags \ 124 | MONITOR_F_SUB | MONITOR_F_PERSISTENT; 125 126 if ( monitor_cache_add( mi, e, e_time ) ) { 127 Debug( LDAP_DEBUG_ANY, 128 "monitor_subsys_time_init: " 129 "unable to add entry \"%s,%s\"\n", 130 bv.bv_val, ms->mss_ndn.bv_val ); 131 return( -1 ); 132 } 133 134 /* 135 * Uptime 136 */ 137 BER_BVSTR( &bv, "cn=Uptime" ); 138 e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv, 139 mi->mi_oc_monitoredObject, NULL, NULL ); 140 if ( e == NULL ) { 141 Debug( LDAP_DEBUG_ANY, 142 "monitor_subsys_time_init: " 143 "unable to create entry \"%s,%s\"\n", 144 bv.bv_val, ms->mss_ndn.bv_val ); 145 return( -1 ); 146 } 147 BER_BVSTR( &value, "0" ); 148 attr_merge_normalize_one( e, mi->mi_ad_monitoredInfo, 149 &value, NULL ); 150 151 mp = monitor_entrypriv_create(); 152 if ( mp == NULL ) { 153 return -1; 154 } 155 e->e_private = ( void * )mp; 156 mp->mp_info = ms; 157 mp->mp_flags = ms->mss_flags \ 158 | MONITOR_F_SUB | MONITOR_F_PERSISTENT; 159 160 if ( monitor_cache_add( mi, e, e_time ) ) { 161 Debug( LDAP_DEBUG_ANY, 162 "monitor_subsys_time_init: " 163 "unable to add entry \"%s,%s\"\n", 164 bv.bv_val, ms->mss_ndn.bv_val ); 165 return( -1 ); 166 } 167 168 monitor_cache_release( mi, e_time ); 169 170 return( 0 ); 171 } 172 173 static int 174 monitor_subsys_time_update( 175 Operation *op, 176 SlapReply *rs, 177 Entry *e ) 178 { 179 monitor_info_t *mi = ( monitor_info_t * )op->o_bd->be_private; 180 static struct berval bv_current = BER_BVC( "cn=current" ), 181 bv_uptime = BER_BVC( "cn=uptime" ); 182 struct berval rdn; 183 184 assert( mi != NULL ); 185 assert( e != NULL ); 186 187 dnRdn( &e->e_nname, &rdn ); 188 189 if ( dn_match( &rdn, &bv_current ) ) { 190 struct tm tm; 191 char tmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ]; 192 Attribute *a; 193 ber_len_t len; 194 time_t currtime; 195 196 currtime = slap_get_time(); 197 198 ldap_pvt_gmtime( &currtime, &tm ); 199 lutil_gentime( tmbuf, sizeof( tmbuf ), &tm ); 200 201 len = strlen( tmbuf ); 202 203 a = attr_find( e->e_attrs, mi->mi_ad_monitorTimestamp ); 204 if ( a == NULL ) { 205 return rs->sr_err = LDAP_OTHER; 206 } 207 208 assert( len == a->a_vals[ 0 ].bv_len ); 209 AC_MEMCPY( a->a_vals[ 0 ].bv_val, tmbuf, len ); 210 211 /* FIXME: touch modifyTimestamp? */ 212 213 } else if ( dn_match( &rdn, &bv_uptime ) ) { 214 Attribute *a; 215 double diff; 216 char buf[ BACKMONITOR_BUFSIZE ]; 217 struct berval bv; 218 219 a = attr_find( e->e_attrs, mi->mi_ad_monitoredInfo ); 220 if ( a == NULL ) { 221 return rs->sr_err = LDAP_OTHER; 222 } 223 224 diff = difftime( slap_get_time(), starttime ); 225 bv.bv_len = snprintf( buf, sizeof( buf ), "%lu", 226 (unsigned long) diff ); 227 bv.bv_val = buf; 228 229 ber_bvreplace( &a->a_vals[ 0 ], &bv ); 230 if ( a->a_nvals != a->a_vals ) { 231 ber_bvreplace( &a->a_nvals[ 0 ], &bv ); 232 } 233 234 /* FIXME: touch modifyTimestamp? */ 235 } 236 237 return SLAP_CB_CONTINUE; 238 } 239 240