]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/stack/stack.c
Massive constification.
[thirdparty/openssl.git] / crypto / stack / stack.c
1 /* crypto/stack/stack.c */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59 /* Code for stacks
60 * Author - Eric Young v 1.0
61 * 1.2 eay 12-Mar-97 - Modified sk_find so that it _DOES_ return the
62 * lowest index for the seached item.
63 *
64 * 1.1 eay - Take from netdb and added to SSLeay
65 *
66 * 1.0 eay - First version 29/07/92
67 */
68 #include <stdio.h>
69 #include "cryptlib.h"
70 #include "stack.h"
71
72 #undef MIN_NODES
73 #define MIN_NODES 4
74
75 const char *STACK_version="Stack" OPENSSL_VERSION_PTEXT;
76
77 #ifndef NOPROTO
78 #define FP_ICC (int (*)(const void *,const void *))
79 #else
80 #define FP_ICC
81 #endif
82
83 #include <errno.h>
84
85 int (*sk_set_cmp_func(sk,c))()
86 STACK *sk;
87 int (*c)();
88 {
89 int (*old)()=sk->comp;
90
91 if (sk->comp != c)
92 sk->sorted=0;
93 sk->comp=c;
94
95 return old;
96 }
97
98 STACK *sk_dup(sk)
99 STACK *sk;
100 {
101 STACK *ret;
102 char **s;
103
104 if ((ret=sk_new(sk->comp)) == NULL) goto err;
105 s=(char **)Realloc((char *)ret->data,
106 (unsigned int)sizeof(char *)*sk->num_alloc);
107 if (s == NULL) goto err;
108 ret->data=s;
109
110 ret->num=sk->num;
111 memcpy(ret->data,sk->data,sizeof(char *)*sk->num);
112 ret->sorted=sk->sorted;
113 ret->num_alloc=sk->num_alloc;
114 ret->comp=sk->comp;
115 return(ret);
116 err:
117 return(NULL);
118 }
119
120 STACK *sk_new(c)
121 int (*c)();
122 {
123 STACK *ret;
124 int i;
125
126 if ((ret=(STACK *)Malloc(sizeof(STACK))) == NULL)
127 goto err0;
128 if ((ret->data=(char **)Malloc(sizeof(char *)*MIN_NODES)) == NULL)
129 goto err1;
130 for (i=0; i<MIN_NODES; i++)
131 ret->data[i]=NULL;
132 ret->comp=c;
133 ret->num_alloc=MIN_NODES;
134 ret->num=0;
135 ret->sorted=0;
136 return(ret);
137 err1:
138 Free((char *)ret);
139 err0:
140 return(NULL);
141 }
142
143 int sk_insert(st,data,loc)
144 STACK *st;
145 char *data;
146 int loc;
147 {
148 char **s;
149
150 if (st->num_alloc <= st->num+1)
151 {
152 s=(char **)Realloc((char *)st->data,
153 (unsigned int)sizeof(char *)*st->num_alloc*2);
154 if (s == NULL)
155 return(0);
156 st->data=s;
157 st->num_alloc*=2;
158 }
159 if ((loc >= (int)st->num) || (loc < 0))
160 st->data[st->num]=data;
161 else
162 {
163 int i;
164 char **f,**t;
165
166 f=(char **)st->data;
167 t=(char **)&(st->data[1]);
168 for (i=st->num; i>=loc; i--)
169 t[i]=f[i];
170
171 #ifdef undef /* no memmove on sunos :-( */
172 memmove( (char *)&(st->data[loc+1]),
173 (char *)&(st->data[loc]),
174 sizeof(char *)*(st->num-loc));
175 #endif
176 st->data[loc]=data;
177 }
178 st->num++;
179 st->sorted=0;
180 return(st->num);
181 }
182
183 char *sk_delete_ptr(st,p)
184 STACK *st;
185 char *p;
186 {
187 int i;
188
189 for (i=0; i<st->num; i++)
190 if (st->data[i] == p)
191 return(sk_delete(st,i));
192 return(NULL);
193 }
194
195 char *sk_delete(st,loc)
196 STACK *st;
197 int loc;
198 {
199 char *ret;
200 int i,j;
201
202 if ((st->num == 0) || (loc < 0) || (loc >= st->num)) return(NULL);
203
204 ret=st->data[loc];
205 if (loc != st->num-1)
206 {
207 j=st->num-1;
208 for (i=loc; i<j; i++)
209 st->data[i]=st->data[i+1];
210 /* In theory memcpy is not safe for this
211 * memcpy( &(st->data[loc]),
212 * &(st->data[loc+1]),
213 * sizeof(char *)*(st->num-loc-1));
214 */
215 }
216 st->num--;
217 return(ret);
218 }
219
220 int sk_find(st,data)
221 STACK *st;
222 char *data;
223 {
224 char **r;
225 int i;
226 int (*comp_func)();
227
228 if (st->comp == NULL)
229 {
230 for (i=0; i<st->num; i++)
231 if (st->data[i] == data)
232 return(i);
233 return(-1);
234 }
235 comp_func=(int (*)())st->comp;
236 if (!st->sorted)
237 {
238 qsort((char *)st->data,st->num,sizeof(char *),FP_ICC comp_func);
239 st->sorted=1;
240 }
241 if (data == NULL) return(-1);
242 r=(char **)bsearch(&data,(char *)st->data,
243 st->num,sizeof(char *),FP_ICC comp_func);
244 if (r == NULL) return(-1);
245 i=(int)(r-st->data);
246 for ( ; i>0; i--)
247 if ((*st->comp)(&(st->data[i-1]),&data) < 0)
248 break;
249 return(i);
250 }
251
252 int sk_push(st,data)
253 STACK *st;
254 char *data;
255 {
256 return(sk_insert(st,data,st->num));
257 }
258
259 int sk_unshift(st,data)
260 STACK *st;
261 char *data;
262 {
263 return(sk_insert(st,data,0));
264 }
265
266 char *sk_shift(st)
267 STACK *st;
268 {
269 if (st == NULL) return(NULL);
270 if (st->num <= 0) return(NULL);
271 return(sk_delete(st,0));
272 }
273
274 char *sk_pop(st)
275 STACK *st;
276 {
277 if (st == NULL) return(NULL);
278 if (st->num <= 0) return(NULL);
279 return(sk_delete(st,st->num-1));
280 }
281
282 void sk_zero(st)
283 STACK *st;
284 {
285 if (st == NULL) return;
286 if (st->num <= 0) return;
287 memset((char *)st->data,0,sizeof(st->data)*st->num);
288 st->num=0;
289 }
290
291 void sk_pop_free(st,func)
292 STACK *st;
293 void (*func)();
294 {
295 int i;
296
297 if (st == NULL) return;
298 for (i=0; i<st->num; i++)
299 if (st->data[i] != NULL)
300 func(st->data[i]);
301 sk_free(st);
302 }
303
304 void sk_free(st)
305 STACK *st;
306 {
307 if (st == NULL) return;
308 if (st->data != NULL) Free((char *)st->data);
309 Free((char *)st);
310 }
311