Commit | Line | Data |
---|---|---|
04c6839a WJ |
1 | /* oc.c - Object Class routines */ |
2 | ||
3 | #ifndef lint | |
4 | static char *rcsid = "$Header: /f/osi/dsap/common/RCS/oc.c,v 7.6 91/02/22 09:19:43 mrose Interim $"; | |
5 | #endif | |
6 | ||
7 | /* | |
8 | * $Header: /f/osi/dsap/common/RCS/oc.c,v 7.6 91/02/22 09:19:43 mrose Interim $ | |
9 | * | |
10 | * | |
11 | * $Log: oc.c,v $ | |
12 | * Revision 7.6 91/02/22 09:19:43 mrose | |
13 | * Interim 6.8 | |
14 | * | |
15 | * Revision 7.5 90/11/20 15:29:15 mrose | |
16 | * cjr | |
17 | * | |
18 | * Revision 7.4 90/10/17 11:42:19 mrose | |
19 | * sync | |
20 | * | |
21 | * Revision 7.3 90/07/09 14:34:47 mrose | |
22 | * sync | |
23 | * | |
24 | * Revision 7.2 90/03/15 11:17:41 mrose | |
25 | * quipu-sync | |
26 | * | |
27 | * Revision 7.1 90/01/11 23:49:43 mrose | |
28 | * lint | |
29 | * | |
30 | * Revision 7.0 89/11/23 21:42:31 mrose | |
31 | * Release 6.0 | |
32 | * | |
33 | */ | |
34 | ||
35 | /* | |
36 | * NOTICE | |
37 | * | |
38 | * Acquisition, use, and distribution of this module and related | |
39 | * materials are subject to the restrictions of a license agreement. | |
40 | * Consult the Preface in the User's Manual for the full terms of | |
41 | * this agreement. | |
42 | * | |
43 | */ | |
44 | ||
45 | ||
46 | /* LINTLIBRARY */ | |
47 | ||
48 | #include "quipu/util.h" | |
49 | #include "quipu/entry.h" | |
50 | #include "tailor.h" | |
51 | ||
52 | extern LLog * log_dsap; | |
53 | extern short oc_sntx; | |
54 | extern IFP oc_hier; | |
55 | extern IFP oc_avsprint; | |
56 | ||
57 | objectclass * oc_add (oid) | |
58 | OID oid; | |
59 | { | |
60 | oid_table * Current; | |
61 | extern objectclass ocOIDTable[]; | |
62 | extern int ocNumEntries; | |
63 | ||
64 | Current = &ocOIDTable[ocNumEntries].oc_ot; | |
65 | if (oid == NULLOID) | |
66 | Current->ot_oid = NULLOID; | |
67 | else | |
68 | Current->ot_oid = oid_cpy (oid); | |
69 | Current->ot_name = strdup(oid2ode_aux(oid,0)); | |
70 | Current->ot_stroid = strdup(sprintoid(oid)); | |
71 | add_entry_aux (Current->ot_name,(caddr_t)&ocOIDTable[ocNumEntries],3,NULLCP); | |
72 | ocOIDTable[ocNumEntries].oc_hierachy = NULLOCSEQ; | |
73 | ocOIDTable[ocNumEntries].oc_may = NULLTABLE_SEQ; | |
74 | ocOIDTable[ocNumEntries].oc_must = NULLTABLE_SEQ; | |
75 | return (&ocOIDTable[ocNumEntries++]); | |
76 | } | |
77 | ||
78 | objectclass * str2oc (str) | |
79 | char * str; | |
80 | { | |
81 | char * ptr; | |
82 | char * get_oid (); | |
83 | objectclass *oc; | |
84 | ||
85 | if ((oc = name2oc (str)) != NULLOBJECTCLASS) | |
86 | return (oc); | |
87 | ||
88 | /* unknown object class -- need to add to table */ | |
89 | if ((ptr = get_oid (str)) == NULLCP) { | |
90 | parse_error ("Object class %s unknown",str); | |
91 | return (NULLOBJECTCLASS); | |
92 | } | |
93 | ||
94 | return (oc_add (str2oid(ptr))); | |
95 | } | |
96 | ||
97 | static AV_Sequence new_oc_avs (oc) | |
98 | objectclass * oc; | |
99 | { | |
100 | AV_Sequence avs; | |
101 | ||
102 | avs = avs_comp_alloc(); | |
103 | avs->avseq_next = NULLAV; | |
104 | avs->avseq_av.av_syntax = oc_sntx; | |
105 | avs->avseq_av.av_struct = (caddr_t) oc; | |
106 | return (avs); | |
107 | } | |
108 | ||
109 | static AV_Sequence str2oc_hier (str) | |
110 | char * str; | |
111 | { | |
112 | AV_Sequence avs = NULLAV; | |
113 | objectclass * oc; | |
114 | char * ptr, *save, val; | |
115 | ||
116 | str = SkipSpace (str); | |
117 | ||
118 | while ((ptr = index (str,'&')) != 0) { | |
119 | save = ptr++; | |
120 | save--; | |
121 | if (! isspace (*save)) | |
122 | save++; | |
123 | val = *save; | |
124 | *save = 0; | |
125 | ||
126 | if ((oc = str2oc (str)) == NULLOBJECTCLASS) | |
127 | return (NULLAV); | |
128 | if (avs == NULLAV) | |
129 | avs = new_oc_avs (oc); | |
130 | else | |
131 | add_oc_avs (oc,&avs); | |
132 | add_hierarchy (oc,&avs); | |
133 | ||
134 | *save = val; | |
135 | str = SkipSpace(ptr); | |
136 | } | |
137 | ||
138 | if ((oc = str2oc (str)) == NULLOBJECTCLASS) | |
139 | return (NULLAV); | |
140 | if (avs == NULLAV) | |
141 | avs = new_oc_avs (oc); | |
142 | else | |
143 | add_oc_avs (oc,&avs); | |
144 | add_hierarchy (oc,&avs); | |
145 | ||
146 | return (avs); | |
147 | } | |
148 | ||
149 | add_oc_avs (oc,avsp) | |
150 | objectclass * oc; | |
151 | AV_Sequence *avsp; | |
152 | { | |
153 | AV_Sequence loop; | |
154 | objectclass *ocp; | |
155 | ||
156 | /* see if we already have oc in heirarchy ... */ | |
157 | ||
158 | for (loop = *avsp; loop != NULLAV; loop = loop->avseq_next) { | |
159 | ocp = (objectclass *)loop->avseq_av.av_struct; | |
160 | if (oc == ocp) | |
161 | return; | |
162 | } | |
163 | *avsp = avs_merge (*avsp,new_oc_avs(oc)); | |
164 | } | |
165 | ||
166 | static add_hierarchy (oc,avsp) | |
167 | objectclass * oc; | |
168 | AV_Sequence *avsp; | |
169 | { | |
170 | struct oc_seq * oidseq; | |
171 | ||
172 | for (oidseq = oc->oc_hierachy; | |
173 | oidseq != NULLOCSEQ; oidseq = oidseq->os_next) { | |
174 | add_oc_avs (oidseq->os_oc,avsp); | |
175 | add_hierarchy (oidseq->os_oc,avsp); | |
176 | } | |
177 | } | |
178 | ||
179 | ||
180 | static in_hierarchy (a,b) | |
181 | AV_Sequence a, b; | |
182 | { | |
183 | struct oc_seq * oidseq; | |
184 | objectclass *oca, *ocb; | |
185 | ||
186 | if ((a == NULLAV) || (a->avseq_av.av_syntax != oc_sntx) || (a->avseq_av.av_struct == NULL)) | |
187 | return (FALSE); | |
188 | ||
189 | if ((b == NULLAV) || (b->avseq_av.av_syntax != oc_sntx) || (b->avseq_av.av_struct == NULL)) | |
190 | return (FALSE); | |
191 | ||
192 | oca = (objectclass *) a->avseq_av.av_struct; | |
193 | ocb = (objectclass *) b->avseq_av.av_struct; | |
194 | ||
195 | for (oidseq = ocb->oc_hierachy; | |
196 | oidseq != NULLOCSEQ; oidseq = oidseq->os_next) | |
197 | if (objclass_cmp(oca,oidseq->os_oc) == 0) | |
198 | return (TRUE); | |
199 | ||
200 | return (FALSE); | |
201 | } | |
202 | ||
203 | static oc_print_avs (ps,avs,format) /* need to use this somehow !!! */ | |
204 | PS ps; | |
205 | AV_Sequence avs; | |
206 | int format; | |
207 | { | |
208 | AV_Sequence newavs; | |
209 | char found; | |
210 | char printed = FALSE; | |
211 | ||
212 | if (avs == NULLAV) | |
213 | return; | |
214 | ||
215 | if (format != READOUT) | |
216 | DLOG (log_dsap,LLOG_EXCEPTIONS,("invalid call to oc_print")); | |
217 | ||
218 | for ( ; avs->avseq_next != NULLAV ; avs=avs->avseq_next) { | |
219 | found = FALSE; | |
220 | for (newavs = avs->avseq_next; newavs != NULLAV; newavs=newavs->avseq_next) | |
221 | if (in_hierarchy(avs,newavs) == TRUE) { | |
222 | found = TRUE; | |
223 | break; | |
224 | } | |
225 | ||
226 | if (found == FALSE) { | |
227 | if (printed == TRUE) | |
228 | ps_print (ps," & "); | |
229 | AttrV_print (ps,&avs->avseq_av,format); | |
230 | printed = TRUE; | |
231 | } | |
232 | } | |
233 | ||
234 | if (printed == TRUE) | |
235 | ps_print (ps," & "); | |
236 | AttrV_print (ps,&avs->avseq_av,format); | |
237 | } | |
238 | ||
239 | objectclass_cmp (a,b) | |
240 | objectclass *a, *b; | |
241 | { | |
242 | /* macro ! */ | |
243 | ||
244 | return objclass_cmp(a,b); | |
245 | } | |
246 | ||
247 | static objectclass * oc_cpy (oc) | |
248 | objectclass * oc; | |
249 | { | |
250 | return (oc); /* static table !!! */ | |
251 | } | |
252 | ||
253 | check_in_oc (oid,avs) | |
254 | OID oid; | |
255 | AV_Sequence avs; | |
256 | { | |
257 | objectclass * oc; | |
258 | ||
259 | for (; avs != NULLAV; avs = avs->avseq_next) { | |
260 | oc = (objectclass *) avs->avseq_av.av_struct; | |
261 | if (oc == NULLOBJECTCLASS) | |
262 | continue; | |
263 | if (oid_cmp(oid,oc->oc_ot.ot_oid) == 0) | |
264 | return (TRUE); | |
265 | } | |
266 | ||
267 | return (FALSE); | |
268 | } | |
269 | ||
270 | /* ARGSUSED */ | |
271 | static oc_free (oc) | |
272 | objectclass * oc; | |
273 | { | |
274 | ; /* static table !!! */ | |
275 | } | |
276 | ||
277 | static PE oc_enc (oc) | |
278 | objectclass *oc; | |
279 | { | |
280 | return (oid2prim(oc->oc_ot.ot_oid)); | |
281 | } | |
282 | ||
283 | ||
284 | static objectclass * oc_dec (pe) | |
285 | PE pe; | |
286 | { | |
287 | OID oid; | |
288 | objectclass *oc; | |
289 | ||
290 | if (! test_prim_pe (pe,PE_CLASS_UNIV,PE_PRIM_OID)) | |
291 | return NULLOBJECTCLASS; | |
292 | ||
293 | if ((oid = prim2oid (pe)) == NULLOID) | |
294 | return NULLOBJECTCLASS; | |
295 | ||
296 | if ((oc = oid2oc (oid)) != NULLOBJECTCLASS) | |
297 | return (oc); | |
298 | ||
299 | return (oc_add(oid)); | |
300 | } | |
301 | ||
302 | ||
303 | ||
304 | oc_print (ps,oc,format) | |
305 | PS ps; | |
306 | objectclass * oc; | |
307 | int format; | |
308 | { | |
309 | extern int oidformat; | |
310 | ||
311 | if ( format != READOUT) | |
312 | ps_printf (ps,"%s",oc2name (oc,OIDPART)); | |
313 | else | |
314 | ps_printf (ps,"%s",oc2name (oc,oidformat)); | |
315 | } | |
316 | ||
317 | objectclass_syntax () | |
318 | { | |
319 | ||
320 | oc_sntx = add_attribute_syntax ("objectclass", | |
321 | (IFP) oc_enc, (IFP) oc_dec, | |
322 | (IFP) str2oc, oc_print, | |
323 | (IFP) oc_cpy, objectclass_cmp, | |
324 | oc_free, NULLCP, | |
325 | NULLIFP, FALSE ); | |
326 | ||
327 | oc_hier = (IFP) str2oc_hier; | |
328 | oc_avsprint = (IFP) oc_print_avs; | |
329 | want_oc_hierarchy (); | |
330 | ||
331 | } |