+ return p != e ? LDAP_INVALID_SYNTAX : LDAP_SUCCESS;
+}
+
+#ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
+
+#if 0
+static int
+xutcTimeNormalize(
+ Syntax *syntax,
+ struct berval *val,
+ struct berval *normalized )
+{
+ int parts[9], rc;
+
+ rc = check_time_syntax(val, 1, parts, NULL);
+ if (rc != LDAP_SUCCESS) {
+ return rc;
+ }
+
+ normalized->bv_val = ch_malloc( 14 );
+ if ( normalized->bv_val == NULL ) {
+ return LBER_ERROR_MEMORY;
+ }
+
+ sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02dZ",
+ parts[1], parts[2] + 1, parts[3] + 1,
+ parts[4], parts[5], parts[6] );
+ normalized->bv_len = 13;
+
+ return LDAP_SUCCESS;
+}
+#endif /* 0 */
+
+static int
+utcTimeValidate(
+ Syntax *syntax,
+ struct berval *in )
+{
+ int parts[9];
+ return check_time_syntax(in, 1, parts, NULL);
+}
+
+#endif /* SUPPORT_OBSOLETE_UTC_SYNTAX */
+
+static int
+generalizedTimeValidate(
+ Syntax *syntax,
+ struct berval *in )
+{
+ int parts[9];
+ struct berval fraction;
+ return check_time_syntax(in, 0, parts, &fraction);
+}
+
+static int
+generalizedTimeNormalize(
+ slap_mask_t usage,
+ Syntax *syntax,
+ MatchingRule *mr,
+ struct berval *val,
+ struct berval *normalized,
+ void *ctx )
+{
+ int parts[9], rc;
+ unsigned int len;
+ struct berval fraction;
+
+ rc = check_time_syntax(val, 0, parts, &fraction);
+ if (rc != LDAP_SUCCESS) {
+ return rc;
+ }
+
+ len = sizeof("YYYYmmddHHMMSSZ")-1 + fraction.bv_len;
+ normalized->bv_val = slap_sl_malloc( len + 1, ctx );
+ if ( BER_BVISNULL( normalized ) ) {
+ return LBER_ERROR_MEMORY;
+ }
+
+ sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02d",
+ parts[0], parts[1], parts[2] + 1, parts[3] + 1,
+ parts[4], parts[5], parts[6] );
+ if ( !BER_BVISEMPTY( &fraction ) ) {
+ memcpy( normalized->bv_val + sizeof("YYYYmmddHHMMSSZ")-2,
+ fraction.bv_val, fraction.bv_len );
+ normalized->bv_val[sizeof("YYYYmmddHHMMSSZ")-2] = '.';
+ }
+ strcpy( normalized->bv_val + len-1, "Z" );
+ normalized->bv_len = len;
+
+ return LDAP_SUCCESS;
+}
+
+static int
+generalizedTimeOrderingMatch(
+ int *matchp,
+ slap_mask_t flags,
+ Syntax *syntax,
+ MatchingRule *mr,
+ struct berval *value,
+ void *assertedValue )
+{
+ struct berval *asserted = (struct berval *) assertedValue;
+ ber_len_t v_len = value->bv_len;
+ ber_len_t av_len = asserted->bv_len;
+
+ /* ignore trailing 'Z' when comparing */
+ int match = memcmp( value->bv_val, asserted->bv_val,
+ (v_len < av_len ? v_len : av_len) - 1 );
+ if ( match == 0 ) match = v_len - av_len;
+
+ *matchp = match;
+ return LDAP_SUCCESS;
+}
+
+/* Index generation function */
+int generalizedTimeIndexer(
+ slap_mask_t use,
+ slap_mask_t flags,
+ Syntax *syntax,
+ MatchingRule *mr,
+ struct berval *prefix,
+ BerVarray values,
+ BerVarray *keysp,
+ void *ctx )
+{
+ int i, j;
+ size_t slen, mlen;
+ BerVarray keys;
+ char tmp[5];
+ BerValue bvtmp; /* 40 bit index */
+ struct lutil_tm tm;
+ struct lutil_timet tt;
+
+ bvtmp.bv_len = sizeof(tmp);
+ bvtmp.bv_val = tmp;
+ for( i=0; values[i].bv_val != NULL; i++ ) {
+ /* just count them */
+ }
+
+ /* we should have at least one value at this point */
+ assert( i > 0 );
+
+ keys = slap_sl_malloc( sizeof( struct berval ) * (i+1), ctx );
+
+ /* GeneralizedTime YYYYmmddHH[MM[SS]][(./,)d...](Z|(+/-)HH[MM]) */
+ for( i=0, j=0; values[i].bv_val != NULL; i++ ) {
+ assert(values[i].bv_val != NULL && values[i].bv_len >= 10);
+ /* Use 40 bits of time for key */
+ if ( lutil_parsetime( values[i].bv_val, &tm ) == 0 ) {
+ lutil_tm2time( &tm, &tt );
+ tmp[0] = tt.tt_gsec & 0xff;
+ tmp[4] = tt.tt_sec & 0xff;
+ tt.tt_sec >>= 8;
+ tmp[3] = tt.tt_sec & 0xff;
+ tt.tt_sec >>= 8;
+ tmp[2] = tt.tt_sec & 0xff;
+ tt.tt_sec >>= 8;
+ tmp[1] = tt.tt_sec & 0xff;
+
+ ber_dupbv_x(&keys[j++], &bvtmp, ctx );
+ }
+ }
+
+ keys[j].bv_val = NULL;
+ keys[j].bv_len = 0;
+
+ *keysp = keys;
+