]> git.sur5r.net Git - openldap/blob - servers/slapd/oidm.c
More ldapbis cleanup
[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-2006 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 = NULL;
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                 if (om) SLAP_FREE( om );
111                 return 1;
112         }
113
114         oid = oidm_find( argv[1] );
115         if( oid != NULL ) {
116                 fprintf( stderr,
117                         "%s: line %d: "
118                         "ObjectIdentifier \"%s\" previously defined \"%s\"",
119                         fname, lineno, argv[1], oid );
120                 SLAP_FREE( oid );
121                 return 1;
122         }
123
124         om = (OidMacro *) SLAP_CALLOC( sizeof(OidMacro), 1 );
125         if( om == NULL ) {
126                 Debug( LDAP_DEBUG_ANY, "parse_oidm: SLAP_CALLOC failed", 0, 0, 0 );
127                 return 1;
128         }
129
130         om->som_names = NULL;
131         om->som_subs = NULL;
132         ber_str2bv( argv[1], 0, 1, &bv );
133         ber_bvarray_add( &om->som_names, &bv );
134         ber_str2bv( argv[2], 0, 1, &bv );
135         ber_bvarray_add( &om->som_subs, &bv );
136         om->som_oid.bv_val = oidm_find( argv[2] );
137
138         if (!om->som_oid.bv_val) {
139                 fprintf( stderr, "%s: line %d: OID %s not recognized\n",
140                         fname, lineno, argv[2] );
141                 goto usage;
142         }
143
144         if (om->som_oid.bv_val == argv[2]) {
145                 om->som_oid.bv_val = ch_strdup( argv[2] );
146         }
147
148         om->som_oid.bv_len = strlen( om->som_oid.bv_val );
149         if ( !user )
150                 om->som_flags |= SLAP_OM_HARDCODE;
151
152         LDAP_STAILQ_INSERT_TAIL( &om_list, om, som_next );
153         if ( rom ) *rom = om;
154         return 0;
155 }
156
157 void oidm_unparse( BerVarray *res, OidMacro *start, OidMacro *end, int sys )
158 {
159         OidMacro *om;
160         int i, j, num;
161         struct berval *bva = NULL, idx;
162         char ibuf[32], *ptr;
163
164         if ( !start )
165                 start = LDAP_STAILQ_FIRST( &om_list );
166
167         /* count the result size */
168         i = 0;
169         for ( om=start; om; om=LDAP_STAILQ_NEXT(om, som_next)) {
170                 if ( sys && !(om->som_flags & SLAP_OM_HARDCODE)) continue;
171                 for ( j=0; !BER_BVISNULL(&om->som_names[j]); j++ );
172                 i += j;
173                 if ( om == end ) break;
174         }
175         num = i;
176         if (!i) return;
177
178         bva = ch_malloc( (num+1) * sizeof(struct berval) );
179         BER_BVZERO( bva+num );
180         idx.bv_val = ibuf;
181         if ( sys ) {
182                 idx.bv_len = 0;
183                 ibuf[0] = '\0';
184         }
185         for ( i=0,om=start; om; om=LDAP_STAILQ_NEXT(om, som_next)) {
186                 if ( sys && !(om->som_flags & SLAP_OM_HARDCODE)) continue;
187                 for ( j=0; !BER_BVISNULL(&om->som_names[j]); i++,j++ ) {
188                         if ( !sys ) {
189                                 idx.bv_len = sprintf(idx.bv_val, "{%d}", i );
190                         }
191                         bva[i].bv_len = idx.bv_len + om->som_names[j].bv_len +
192                                 om->som_subs[j].bv_len + 1;
193                         bva[i].bv_val = ch_malloc( bva[i].bv_len + 1 );
194                         ptr = lutil_strcopy( bva[i].bv_val, ibuf );
195                         ptr = lutil_strcopy( ptr, om->som_names[j].bv_val );
196                         *ptr++ = ' ';
197                         strcpy( ptr, om->som_subs[j].bv_val );
198                 }
199                 if ( i>=num ) break;
200                 if ( om == end ) break;
201         }
202         *res = bva;
203 }