xref: /freebsd/crypto/krb5/src/ccapi/server/ccs_client.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1 /* ccapi/server/ccs_client.c */
2 /*
3  * Copyright 2006 Massachusetts Institute of Technology.
4  * All Rights Reserved.
5  *
6  * Export of this software from the United States of America may
7  * require a specific license from the United States Government.
8  * It is the responsibility of any person or organization contemplating
9  * export to obtain such a license before exporting.
10  *
11  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
12  * distribute this software and its documentation for any purpose and
13  * without fee is hereby granted, provided that the above copyright
14  * notice appear in all copies and that both that copyright notice and
15  * this permission notice appear in supporting documentation, and that
16  * the name of M.I.T. not be used in advertising or publicity pertaining
17  * to distribution of the software without specific, written prior
18  * permission.  Furthermore if you modify this software you must label
19  * your software as modified software and not distribute it in such a
20  * fashion that it might be confused with the original M.I.T. software.
21  * M.I.T. makes no representations about the suitability of
22  * this software for any purpose.  It is provided "as is" without express
23  * or implied warranty.
24  */
25 
26 #include "ccs_common.h"
27 
28 struct ccs_client_d {
29     ccs_pipe_t client_pipe;
30 
31     /* The following arrays do not own their contents */
32     ccs_callbackref_array_t callbacks;
33     ccs_iteratorref_array_t iterators;
34 };
35 
36 struct ccs_client_d ccs_client_initializer = { CCS_PIPE_NULL, NULL, NULL };
37 
38 /* ------------------------------------------------------------------------ */
39 
ccs_client_new(ccs_client_t * out_client,ccs_pipe_t in_client_pipe)40 cc_int32 ccs_client_new (ccs_client_t *out_client,
41                          ccs_pipe_t    in_client_pipe)
42 {
43     cc_int32 err = ccNoError;
44     ccs_client_t client = NULL;
45 
46     if (!out_client                     ) { err = cci_check_error (ccErrBadParam); }
47     if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
48 
49     if (!err) {
50         client = malloc (sizeof (*client));
51         if (client) {
52             *client = ccs_client_initializer;
53         } else {
54             err = cci_check_error (ccErrNoMem);
55         }
56     }
57 
58     if (!err) {
59         err = ccs_callbackref_array_new (&client->callbacks);
60     }
61 
62     if (!err) {
63         err = ccs_iteratorref_array_new (&client->iterators);
64     }
65 
66     if (!err) {
67 	err = ccs_pipe_copy (&client->client_pipe, in_client_pipe);
68     }
69 
70     if (!err) {
71         *out_client = client;
72         client = NULL;
73     }
74 
75     ccs_client_release (client);
76 
77     return cci_check_error (err);
78 }
79 
80 /* ------------------------------------------------------------------------ */
81 
ccs_client_release(ccs_client_t io_client)82 cc_int32 ccs_client_release (ccs_client_t io_client)
83 {
84     cc_int32 err = ccNoError;
85 
86     if (!err && io_client) {
87 	cc_uint64 i;
88 	cc_uint64 callback_count = ccs_callbackref_array_count (io_client->callbacks);
89 	cc_uint64 iterator_count = ccs_iteratorref_array_count (io_client->iterators);
90 
91 	for (i = 0; !err && i < callback_count; i++) {
92 	    ccs_callback_t callback = ccs_callbackref_array_object_at_index (io_client->callbacks, i);
93 
94 	    cci_debug_printf ("%s: Invalidating callback reference %p.",
95                               __FUNCTION__, callback);
96 	    ccs_callback_invalidate (callback);
97 	}
98 
99 	for (i = 0; !err && i < iterator_count; i++) {
100 	    ccs_generic_list_iterator_t iterator = ccs_iteratorref_array_object_at_index (io_client->iterators, i);
101 
102 	    cci_debug_printf ("%s: Invalidating iterator reference %p.",
103                               __FUNCTION__, iterator);
104 	    ccs_generic_list_iterator_invalidate (iterator);
105 	}
106 
107 	ccs_callbackref_array_release (io_client->callbacks);
108 	ccs_iteratorref_array_release (io_client->iterators);
109 	ccs_pipe_release (io_client->client_pipe);
110 	free (io_client);
111     }
112 
113     return cci_check_error (err);
114 }
115 
116 /* ------------------------------------------------------------------------ */
117 
ccs_client_add_callback(ccs_client_t io_client,ccs_callback_t in_callback)118 cc_int32 ccs_client_add_callback (ccs_client_t   io_client,
119 				  ccs_callback_t in_callback)
120 {
121     cc_int32 err = ccNoError;
122 
123     if (!io_client  ) { err = cci_check_error (ccErrBadParam); }
124     if (!in_callback) { err = cci_check_error (ccErrBadParam); }
125 
126      if (!err) {
127         err = ccs_callbackref_array_insert (io_client->callbacks, in_callback,
128 					    ccs_callbackref_array_count (io_client->callbacks));
129      }
130 
131     return cci_check_error (err);
132 }
133 
134 
135 /* ------------------------------------------------------------------------ */
136 
ccs_client_remove_callback(ccs_client_t io_client,ccs_callback_t in_callback)137 cc_int32 ccs_client_remove_callback (ccs_client_t   io_client,
138 				     ccs_callback_t in_callback)
139 {
140     cc_int32 err = ccNoError;
141     cc_uint32 found_callback = 0;
142 
143     if (!io_client) { err = cci_check_error (ccErrBadParam); }
144 
145     if (!err) {
146         cc_uint64 i;
147         cc_uint64 lock_count = ccs_callbackref_array_count (io_client->callbacks);
148 
149         for (i = 0; !err && i < lock_count; i++) {
150             ccs_callback_t callback = ccs_callbackref_array_object_at_index (io_client->callbacks, i);
151 
152             if (callback == in_callback) {
153 		cci_debug_printf ("%s: Removing callback reference %p.", __FUNCTION__, callback);
154 		found_callback = 1;
155 		err = ccs_callbackref_array_remove (io_client->callbacks, i);
156 		break;
157             }
158         }
159     }
160 
161     if (!err && !found_callback) {
162         cci_debug_printf ("%s: WARNING! callback not found.", __FUNCTION__);
163     }
164 
165     return cci_check_error (err);
166 }
167 
168 /* ------------------------------------------------------------------------ */
169 
ccs_client_add_iterator(ccs_client_t io_client,ccs_generic_list_iterator_t in_iterator)170 cc_int32 ccs_client_add_iterator (ccs_client_t                io_client,
171 				  ccs_generic_list_iterator_t in_iterator)
172 {
173     cc_int32 err = ccNoError;
174 
175     if (!io_client  ) { err = cci_check_error (ccErrBadParam); }
176     if (!in_iterator) { err = cci_check_error (ccErrBadParam); }
177 
178     if (!err) {
179         err = ccs_iteratorref_array_insert (io_client->iterators, in_iterator,
180                                             ccs_iteratorref_array_count (io_client->iterators));
181     }
182 
183     return cci_check_error (err);
184 }
185 
186 /* ------------------------------------------------------------------------ */
187 
ccs_client_remove_iterator(ccs_client_t io_client,ccs_generic_list_iterator_t in_iterator)188 cc_int32 ccs_client_remove_iterator (ccs_client_t                io_client,
189 				     ccs_generic_list_iterator_t in_iterator)
190 {
191     cc_int32 err = ccNoError;
192     cc_uint32 found_iterator = 0;
193 
194     if (!io_client) { err = cci_check_error (ccErrBadParam); }
195 
196     if (!err) {
197         cc_uint64 i;
198         cc_uint64 lock_count = ccs_iteratorref_array_count (io_client->iterators);
199 
200         for (i = 0; !err && i < lock_count; i++) {
201             ccs_generic_list_iterator_t iterator = ccs_iteratorref_array_object_at_index (io_client->iterators, i);
202 
203             if (iterator == in_iterator) {
204 		cci_debug_printf ("%s: Removing iterator reference %p.", __FUNCTION__, iterator);
205 		found_iterator = 1;
206 		err = ccs_iteratorref_array_remove (io_client->iterators, i);
207 		break;
208             }
209         }
210     }
211 
212     if (!err && !found_iterator) {
213         cci_debug_printf ("%s: WARNING! iterator not found.", __FUNCTION__);
214     }
215 
216     return cci_check_error (err);
217 }
218 
219 /* ------------------------------------------------------------------------ */
220 
ccs_client_uses_pipe(ccs_client_t in_client,ccs_pipe_t in_pipe,cc_uint32 * out_uses_pipe)221 cc_int32 ccs_client_uses_pipe (ccs_client_t  in_client,
222                                ccs_pipe_t    in_pipe,
223                                cc_uint32    *out_uses_pipe)
224 {
225     cc_int32 err = ccNoError;
226 
227     if (!in_client    ) { err = cci_check_error (ccErrBadParam); }
228     if (!in_pipe      ) { err = cci_check_error (ccErrBadParam); }
229     if (!out_uses_pipe) { err = cci_check_error (ccErrBadParam); }
230 
231     if (!err) {
232         err = ccs_pipe_compare (in_client->client_pipe, in_pipe, out_uses_pipe);
233     }
234 
235     return cci_check_error (err);
236 }
237