Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / external / bsd / openldap / dist / servers / slapd / oidm.c
blob0c1062141a52456aa542463d84aaad255b3ab862
1 /* oidm.c - object identifier macro routines */
2 /* $OpenLDAP: pkg/ldap/servers/slapd/oidm.c,v 1.21.2.3 2008/02/11 23:26:44 kurt Exp $ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 1998-2008 The OpenLDAP Foundation.
6 * All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
10 * Public License.
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
17 #include "portable.h"
19 #include <stdio.h>
21 #include <ac/ctype.h>
22 #include <ac/string.h>
23 #include <ac/socket.h>
25 #include "slap.h"
26 #include "lutil.h"
27 #include "config.h"
29 static LDAP_STAILQ_HEAD(OidMacroList, OidMacro) om_list
30 = LDAP_STAILQ_HEAD_INITIALIZER(om_list);
32 OidMacro *om_sys_tail;
34 /* Replace an OID Macro invocation with its full numeric OID.
35 * If the macro is used with "macroname:suffix" append ".suffix"
36 * to the expansion.
38 char *
39 oidm_find(char *oid)
41 OidMacro *om;
43 /* OID macros must start alpha */
44 if ( OID_LEADCHAR( *oid ) ) {
45 return oid;
48 LDAP_STAILQ_FOREACH( om, &om_list, som_next ) {
49 BerVarray names = om->som_names;
51 if( names == NULL ) {
52 continue;
55 for( ; !BER_BVISNULL( names ) ; names++ ) {
56 int pos = dscompare(names->bv_val, oid, ':');
58 if( pos ) {
59 int suflen = strlen(oid + pos);
60 char *tmp = SLAP_MALLOC( om->som_oid.bv_len
61 + suflen + 1);
62 if( tmp == NULL ) {
63 Debug( LDAP_DEBUG_ANY,
64 "oidm_find: SLAP_MALLOC failed", 0, 0, 0 );
65 return NULL;
67 strcpy(tmp, om->som_oid.bv_val);
68 if( suflen ) {
69 suflen = om->som_oid.bv_len;
70 tmp[suflen++] = '.';
71 strcpy(tmp+suflen, oid+pos+1);
73 return tmp;
77 return NULL;
80 void
81 oidm_destroy()
83 OidMacro *om;
84 while( !LDAP_STAILQ_EMPTY( &om_list )) {
85 om = LDAP_STAILQ_FIRST( &om_list );
86 LDAP_STAILQ_REMOVE_HEAD( &om_list, som_next );
88 ber_bvarray_free(om->som_names);
89 ber_bvarray_free(om->som_subs);
90 free(om->som_oid.bv_val);
91 free(om);
96 int
97 parse_oidm(
98 struct config_args_s *c,
99 int user,
100 OidMacro **rom)
102 char *oid, *oidv;
103 OidMacro *om = NULL, *prev = NULL;
104 struct berval bv;
106 oidv = oidm_find( c->argv[2] );
107 if( !oidv ) {
108 snprintf( c->cr_msg, sizeof( c->cr_msg ),
109 "%s: OID %s not recognized",
110 c->argv[0], c->argv[2] );
111 Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
112 "%s %s\n", c->log, c->cr_msg, 0 );
113 return 1;
116 oid = oidm_find( c->argv[1] );
117 if( oid != NULL ) {
118 int rc;
119 snprintf( c->cr_msg, sizeof( c->cr_msg ),
120 "%s: \"%s\" previously defined \"%s\"",
121 c->argv[0], c->argv[1], oid );
122 Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
123 "%s %s\n", c->log, c->cr_msg, 0 );
124 /* Allow duplicate if the definition is identical */
125 rc = strcmp( oid, oidv ) != 0;
126 SLAP_FREE( oid );
127 if ( oidv != c->argv[2] )
128 SLAP_FREE( oidv );
129 return rc;
132 om = (OidMacro *) SLAP_CALLOC( sizeof(OidMacro), 1 );
133 if( om == NULL ) {
134 snprintf( c->cr_msg, sizeof( c->cr_msg ),
135 "%s: SLAP_CALLOC failed", c->argv[0] );
136 Debug( LDAP_DEBUG_ANY,
137 "%s %s\n", c->log, c->cr_msg, 0 );
138 if ( oidv != c->argv[2] )
139 SLAP_FREE( oidv );
140 return 1;
143 om->som_names = NULL;
144 om->som_subs = NULL;
145 ber_str2bv( c->argv[1], 0, 1, &bv );
146 ber_bvarray_add( &om->som_names, &bv );
147 ber_str2bv( c->argv[2], 0, 1, &bv );
148 ber_bvarray_add( &om->som_subs, &bv );
149 om->som_oid.bv_val = oidv;
151 if (om->som_oid.bv_val == c->argv[2]) {
152 om->som_oid.bv_val = ch_strdup( c->argv[2] );
155 om->som_oid.bv_len = strlen( om->som_oid.bv_val );
156 if ( !user ) {
157 om->som_flags |= SLAP_OM_HARDCODE;
158 prev = om_sys_tail;
159 om_sys_tail = om;
162 if ( prev ) {
163 LDAP_STAILQ_INSERT_AFTER( &om_list, prev, om, som_next );
164 } else {
165 LDAP_STAILQ_INSERT_TAIL( &om_list, om, som_next );
167 if ( rom ) *rom = om;
168 return 0;
171 void oidm_unparse( BerVarray *res, OidMacro *start, OidMacro *end, int sys )
173 OidMacro *om;
174 int i, j, num;
175 struct berval *bva = NULL, idx;
176 char ibuf[32], *ptr;
178 if ( !start )
179 start = LDAP_STAILQ_FIRST( &om_list );
181 /* count the result size */
182 i = 0;
183 for ( om=start; om; om=LDAP_STAILQ_NEXT(om, som_next)) {
184 if ( sys && !(om->som_flags & SLAP_OM_HARDCODE)) break;
185 for ( j=0; !BER_BVISNULL(&om->som_names[j]); j++ );
186 i += j;
187 if ( om == end ) break;
189 num = i;
190 if (!i) return;
192 bva = ch_malloc( (num+1) * sizeof(struct berval) );
193 BER_BVZERO( bva+num );
194 idx.bv_val = ibuf;
195 if ( sys ) {
196 idx.bv_len = 0;
197 ibuf[0] = '\0';
199 for ( i=0,om=start; om; om=LDAP_STAILQ_NEXT(om, som_next)) {
200 if ( sys && !(om->som_flags & SLAP_OM_HARDCODE)) break;
201 for ( j=0; !BER_BVISNULL(&om->som_names[j]); i++,j++ ) {
202 if ( !sys ) {
203 idx.bv_len = sprintf(idx.bv_val, "{%d}", i );
205 bva[i].bv_len = idx.bv_len + om->som_names[j].bv_len +
206 om->som_subs[j].bv_len + 1;
207 bva[i].bv_val = ch_malloc( bva[i].bv_len + 1 );
208 ptr = lutil_strcopy( bva[i].bv_val, ibuf );
209 ptr = lutil_strcopy( ptr, om->som_names[j].bv_val );
210 *ptr++ = ' ';
211 strcpy( ptr, om->som_subs[j].bv_val );
213 if ( i>=num ) break;
214 if ( om == end ) break;
216 *res = bva;