]> git.sur5r.net Git - openldap/blob - servers/slapd/oidm.c
ITS#2919 move OpenLDAPtime to OpenLDAPperson
[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 {
100         char *oid;
101         OidMacro *om;
102         struct berval bv;
103
104         if (argc != 3) {
105                 fprintf( stderr, "%s: line %d: too many arguments\n",
106                         fname, lineno );
107 usage:  fprintf( stderr, "\tObjectIdentifier <name> <oid>\n");
108                 return 1;
109         }
110
111         oid = oidm_find( argv[1] );
112         if( oid != NULL ) {
113                 fprintf( stderr,
114                         "%s: line %d: "
115                         "ObjectIdentifier \"%s\" previously defined \"%s\"",
116                         fname, lineno, argv[1], oid );
117                 return 1;
118         }
119
120         om = (OidMacro *) SLAP_MALLOC( sizeof(OidMacro) );
121         if( om == NULL ) {
122                 Debug( LDAP_DEBUG_ANY, "parse_oidm: SLAP_MALLOC failed", 0, 0, 0 );
123                 return 1;
124         }
125
126         LDAP_SLIST_NEXT( om, som_next ) = NULL;
127         om->som_names = NULL;
128         om->som_subs = NULL;
129         ber_str2bv( argv[1], 0, 1, &bv );
130         ber_bvarray_add( &om->som_names, &bv );
131         ber_str2bv( argv[2], 0, 1, &bv );
132         ber_bvarray_add( &om->som_subs, &bv );
133         om->som_oid.bv_val = oidm_find( argv[2] );
134
135         if (!om->som_oid.bv_val) {
136                 fprintf( stderr, "%s: line %d: OID %s not recognized\n",
137                         fname, lineno, argv[2] );
138                 goto usage;
139         }
140
141         if (om->som_oid.bv_val == argv[2]) {
142                 om->som_oid.bv_val = ch_strdup( argv[2] );
143         }
144
145         om->som_oid.bv_len = strlen( om->som_oid.bv_val );
146
147         LDAP_SLIST_INSERT_HEAD( &om_list, om, som_next );
148         return 0;
149 }
150
151 void oidm_unparse( BerVarray *res )
152 {
153         OidMacro *om;
154         int i, j, num;
155         struct berval bv, *bva = NULL, idx;
156         char ibuf[32], *ptr;
157
158         /* count the result size */
159         i = 0;
160         LDAP_SLIST_FOREACH( om, &om_list, som_next ) {
161                 for ( j=0; !BER_BVISNULL(&om->som_names[j]); j++ );
162                 i += j;
163         }
164         num = i;
165         bva = ch_malloc( (num+1) * sizeof(struct berval) );
166         BER_BVZERO( bva+num );
167         idx.bv_val = ibuf;
168         LDAP_SLIST_FOREACH( om, &om_list, som_next ) {
169                 for ( j=0; !BER_BVISNULL(&om->som_names[j]); j++ );
170                 for ( i=num-j, j=0; i<num; i++,j++ ) {
171                         idx.bv_len = sprintf(idx.bv_val, "{%d}", i );
172                         bva[i].bv_len = idx.bv_len + om->som_names[j].bv_len +
173                                 om->som_subs[j].bv_len + 1;
174                         bva[i].bv_val = ch_malloc( bva[i].bv_len + 1 );
175                         ptr = lutil_strcopy( bva[i].bv_val, ibuf );
176                         ptr = lutil_strcopy( ptr, om->som_names[j].bv_val );
177                         *ptr++ = ' ';
178                         ptr = lutil_strcopy( ptr, om->som_subs[j].bv_val );
179                 }
180                 num -= j;
181         }
182         *res = bva;
183 }