]> git.sur5r.net Git - openldap/blob - servers/slapd/oidm.c
25407644a495490c64e336492fde6bf2b787ec55
[openldap] / servers / slapd / oidm.c
1 /* oidm.c - object identifier macro routines */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 1998-2005 The OpenLDAP Foundation.
6  * All rights reserved.
7  *
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.
11  *
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>.
15  */
16
17 #include "portable.h"
18
19 #include <stdio.h>
20
21 #include <ac/ctype.h>
22 #include <ac/string.h>
23 #include <ac/socket.h>
24
25 #include "slap.h"
26 #include "lutil.h"
27
28 static LDAP_STAILQ_HEAD(OidMacroList, slap_oid_macro) om_list
29         = LDAP_STAILQ_HEAD_INITIALIZER(om_list);
30
31 /* Replace an OID Macro invocation with its full numeric OID.
32  * If the macro is used with "macroname:suffix" append ".suffix"
33  * to the expansion.
34  */
35 char *
36 oidm_find(char *oid)
37 {
38         OidMacro *om;
39
40         /* OID macros must start alpha */
41         if ( OID_LEADCHAR( *oid ) )     {
42                 return oid;
43         }
44
45         LDAP_STAILQ_FOREACH( om, &om_list, som_next ) {
46                 BerVarray names = om->som_names;
47
48                 if( names == NULL ) {
49                         continue;
50                 }
51
52                 for( ; !BER_BVISNULL( names ) ; names++ ) {
53                         int pos = dscompare(names->bv_val, oid, ':');
54
55                         if( pos ) {
56                                 int suflen = strlen(oid + pos);
57                                 char *tmp = SLAP_MALLOC( om->som_oid.bv_len
58                                         + suflen + 1);
59                                 if( tmp == NULL ) {
60                                         Debug( LDAP_DEBUG_ANY,
61                                                 "oidm_find: SLAP_MALLOC failed", 0, 0, 0 );
62                                         return NULL;
63                                 }
64                                 strcpy(tmp, om->som_oid.bv_val);
65                                 if( suflen ) {
66                                         suflen = om->som_oid.bv_len;
67                                         tmp[suflen++] = '.';
68                                         strcpy(tmp+suflen, oid+pos+1);
69                                 }
70                                 return tmp;
71                         }
72                 }
73         }
74         return NULL;
75 }
76
77 void
78 oidm_destroy()
79 {
80         OidMacro *om;
81         while( !LDAP_STAILQ_EMPTY( &om_list )) {
82                 om = LDAP_STAILQ_FIRST( &om_list );
83                 LDAP_STAILQ_REMOVE_HEAD( &om_list, som_next );
84
85                 ber_bvarray_free(om->som_names);
86                 ber_bvarray_free(om->som_subs);
87                 free(om->som_oid.bv_val);
88                 free(om);
89                 
90         }
91 }
92
93 int
94 parse_oidm(
95     const char  *fname,
96     int         lineno,
97     int         argc,
98     char        **argv,
99         int             user,
100         OidMacro **rom)
101 {
102         char *oid;
103         OidMacro *om;
104         struct berval bv;
105
106         if (argc != 3) {
107                 fprintf( stderr, "%s: line %d: too many arguments\n",
108                         fname, lineno );
109 usage:  fprintf( stderr, "\tObjectIdentifier <name> <oid>\n");
110                 return 1;
111         }
112
113         oid = oidm_find( argv[1] );
114         if( oid != NULL ) {
115                 fprintf( stderr,
116                         "%s: line %d: "
117                         "ObjectIdentifier \"%s\" previously defined \"%s\"",
118                         fname, lineno, argv[1], oid );
119                 return 1;
120         }
121
122         om = (OidMacro *) SLAP_MALLOC( sizeof(OidMacro) );
123         if( om == NULL ) {
124                 Debug( LDAP_DEBUG_ANY, "parse_oidm: SLAP_MALLOC failed", 0, 0, 0 );
125                 return 1;
126         }
127
128         om->som_names = NULL;
129         om->som_subs = NULL;
130         ber_str2bv( argv[1], 0, 1, &bv );
131         ber_bvarray_add( &om->som_names, &bv );
132         ber_str2bv( argv[2], 0, 1, &bv );
133         ber_bvarray_add( &om->som_subs, &bv );
134         om->som_oid.bv_val = oidm_find( argv[2] );
135
136         if (!om->som_oid.bv_val) {
137                 fprintf( stderr, "%s: line %d: OID %s not recognized\n",
138                         fname, lineno, argv[2] );
139                 goto usage;
140         }
141
142         if (om->som_oid.bv_val == argv[2]) {
143                 om->som_oid.bv_val = ch_strdup( argv[2] );
144         }
145
146         om->som_oid.bv_len = strlen( om->som_oid.bv_val );
147         if ( !user )
148                 om->som_flags |= SLAP_OM_HARDCODE;
149
150         LDAP_STAILQ_INSERT_TAIL( &om_list, om, som_next );
151         if ( rom ) *rom = om;
152         return 0;
153 }
154
155 void oidm_unparse( BerVarray *res, OidMacro *start, OidMacro *end, int sys )
156 {
157         OidMacro *om;
158         int i, j, num;
159         struct berval bv, *bva = NULL, idx;
160         char ibuf[32], *ptr;
161
162         if ( !start )
163                 start = LDAP_STAILQ_FIRST( &om_list );
164
165         /* count the result size */
166         i = 0;
167         for ( om=start; om; om=LDAP_STAILQ_NEXT(om, som_next)) {
168                 if ( sys && !(om->som_flags & SLAP_OM_HARDCODE)) continue;
169                 for ( j=0; !BER_BVISNULL(&om->som_names[j]); j++ );
170                 i += j;
171                 if ( om == end ) break;
172         }
173         num = i;
174         if (!i) return;
175
176         bva = ch_malloc( (num+1) * sizeof(struct berval) );
177         BER_BVZERO( bva+num );
178         idx.bv_val = ibuf;
179         if ( sys ) {
180                 idx.bv_len = 0;
181                 ibuf[0] = '\0';
182         }
183         for ( i=0,om=start; om; om=LDAP_STAILQ_NEXT(om, som_next)) {
184                 if ( sys && !(om->som_flags & SLAP_OM_HARDCODE)) continue;
185                 for ( j=0; !BER_BVISNULL(&om->som_names[j]); i++,j++ ) {
186                         if ( !sys ) {
187                                 idx.bv_len = sprintf(idx.bv_val, "{%d}", i );
188                         }
189                         bva[i].bv_len = idx.bv_len + om->som_names[j].bv_len +
190                                 om->som_subs[j].bv_len + 1;
191                         bva[i].bv_val = ch_malloc( bva[i].bv_len + 1 );
192                         ptr = lutil_strcopy( bva[i].bv_val, ibuf );
193                         ptr = lutil_strcopy( ptr, om->som_names[j].bv_val );
194                         *ptr++ = ' ';
195                         strcpy( ptr, om->som_subs[j].bv_val );
196                 }
197                 if ( i>=num ) break;
198                 if ( om == end ) break;
199         }
200         *res = bva;
201 }