]> git.sur5r.net Git - openldap/blob - servers/slapd/oidm.c
3a20fcde4377fd7fe003024c3470f4290018ce81
[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_SLIST_HEAD(OidMacroList, slap_oid_macro) om_list
29         = LDAP_SLIST_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_SLIST_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_SLIST_EMPTY( &om_list )) {
82                 om = LDAP_SLIST_FIRST( &om_list );
83                 LDAP_SLIST_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 {
101         char *oid;
102         OidMacro *om;
103         struct berval bv;
104
105         if (argc != 3) {
106                 fprintf( stderr, "%s: line %d: too many arguments\n",
107                         fname, lineno );
108 usage:  fprintf( stderr, "\tObjectIdentifier <name> <oid>\n");
109                 return 1;
110         }
111
112         oid = oidm_find( argv[1] );
113         if( oid != NULL ) {
114                 fprintf( stderr,
115                         "%s: line %d: "
116                         "ObjectIdentifier \"%s\" previously defined \"%s\"",
117                         fname, lineno, argv[1], oid );
118                 return 1;
119         }
120
121         om = (OidMacro *) SLAP_MALLOC( sizeof(OidMacro) );
122         if( om == NULL ) {
123                 Debug( LDAP_DEBUG_ANY, "parse_oidm: SLAP_MALLOC failed", 0, 0, 0 );
124                 return 1;
125         }
126
127         LDAP_SLIST_NEXT( om, som_next ) = NULL;
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_SLIST_INSERT_HEAD( &om_list, om, som_next );
151         return 0;
152 }
153
154 void oidm_unparse( BerVarray *res )
155 {
156         OidMacro *om;
157         int i, j, num;
158         struct berval bv, *bva = NULL, idx;
159         char ibuf[32], *ptr;
160
161         /* count the result size */
162         i = 0;
163         LDAP_SLIST_FOREACH( om, &om_list, som_next ) {
164                 for ( j=0; !BER_BVISNULL(&om->som_names[j]); j++ );
165                 i += j;
166         }
167         num = i;
168         bva = ch_malloc( (num+1) * sizeof(struct berval) );
169         BER_BVZERO( bva+num );
170         idx.bv_val = ibuf;
171         LDAP_SLIST_FOREACH( om, &om_list, som_next ) {
172                 for ( j=0; !BER_BVISNULL(&om->som_names[j]); j++ );
173                 for ( i=num-j, j=0; i<num; i++,j++ ) {
174                         idx.bv_len = sprintf(idx.bv_val, "{%d}", i );
175                         bva[i].bv_len = idx.bv_len + om->som_names[j].bv_len +
176                                 om->som_subs[j].bv_len + 1;
177                         bva[i].bv_val = ch_malloc( bva[i].bv_len + 1 );
178                         ptr = lutil_strcopy( bva[i].bv_val, ibuf );
179                         ptr = lutil_strcopy( ptr, om->som_names[j].bv_val );
180                         *ptr++ = ' ';
181                         ptr = lutil_strcopy( ptr, om->som_subs[j].bv_val );
182                 }
183                 num -= j;
184         }
185         *res = bva;
186 }