1
/* crypto/txt_db/txt_db.c */
2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
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.
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).
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.
23
* Redistribution and use in source and binary forms, with or without
24
* modification, are permitted provided that the following conditions
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)"
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
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.]
63
#include <openssl/buffer.h>
64
#include <openssl/txt_db.h>
69
const char TXT_DB_version[]="TXT_DB" OPENSSL_VERSION_PTEXT;
71
TXT_DB *TXT_DB_read(BIO *in, int num)
83
if ((buf=BUF_MEM_new()) == NULL) goto err;
84
if (!BUF_MEM_grow(buf,size)) goto err;
86
if ((ret=(TXT_DB *)OPENSSL_malloc(sizeof(TXT_DB))) == NULL)
91
if ((ret->data=sk_new_null()) == NULL)
93
if ((ret->index=(LHASH **)OPENSSL_malloc(sizeof(LHASH *)*num)) == NULL)
95
if ((ret->qual=(int (**)(char **))OPENSSL_malloc(sizeof(int (**)(char **))*num)) == NULL)
103
add=(num+1)*sizeof(char *);
104
buf->data[size-1]='\0';
111
if (!BUF_MEM_grow_clean(buf,size)) goto err;
113
buf->data[offset]='\0';
114
BIO_gets(in,&(buf->data[offset]),size-offset);
116
if (buf->data[offset] == '\0') break;
117
if ((offset == 0) && (buf->data[0] == '#')) continue;
118
i=strlen(&(buf->data[offset]));
120
if (buf->data[offset-1] != '\n')
124
buf->data[offset-1]='\0'; /* blat the '\n' */
125
if (!(p=(char *)OPENSSL_malloc(add+offset))) goto err;
138
if (*f == '\0') break;
156
if ((n != num) || (*f != '\0'))
158
#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) /* temporaty fix :-( */
159
fprintf(stderr,"wrong number of fields on line %ld (looking for field %d, got %d, '%s' left)\n",ln,num,n,f);
165
if (!sk_push(ret->data,(char *)pp))
167
#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) /* temporaty fix :-( */
168
fprintf(stderr,"failure in sk_push\n");
179
#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)
180
if (er == 1) fprintf(stderr,"OPENSSL_malloc failure\n");
184
if (ret->data != NULL) sk_free(ret->data);
185
if (ret->index != NULL) OPENSSL_free(ret->index);
186
if (ret->qual != NULL) OPENSSL_free(ret->qual);
187
if (ret != NULL) OPENSSL_free(ret);
195
char **TXT_DB_get_by_index(TXT_DB *db, int idx, char **value)
200
if (idx >= db->num_fields)
202
db->error=DB_ERROR_INDEX_OUT_OF_RANGE;
208
db->error=DB_ERROR_NO_INDEX;
211
ret=(char **)lh_retrieve(lh,value);
212
db->error=DB_ERROR_OK;
216
int TXT_DB_create_index(TXT_DB *db, int field, int (*qual)(char **),
217
LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp)
223
if (field >= db->num_fields)
225
db->error=DB_ERROR_INDEX_OUT_OF_RANGE;
228
if ((idx=lh_new(hash,cmp)) == NULL)
230
db->error=DB_ERROR_MALLOC;
236
r=(char **)sk_value(db->data,i);
237
if ((qual != NULL) && (qual(r) == 0)) continue;
238
if ((r=lh_insert(idx,r)) != NULL)
240
db->error=DB_ERROR_INDEX_CLASH;
241
db->arg1=sk_find(db->data,(char *)r);
247
if (db->index[field] != NULL) lh_free(db->index[field]);
248
db->index[field]=idx;
249
db->qual[field]=qual;
253
long TXT_DB_write(BIO *out, TXT_DB *db)
255
long i,j,n,nn,l,tot=0;
260
if ((buf=BUF_MEM_new()) == NULL)
266
pp=(char **)sk_value(db->data,i);
274
if (!BUF_MEM_grow_clean(buf,(int)(l*2+nn))) goto err;
283
if (*f == '\0') break;
284
if (*f == '\t') *(p++)='\\';
291
if (BIO_write(out,buf->data,(int)j) != j)
297
if (buf != NULL) BUF_MEM_free(buf);
301
int TXT_DB_insert(TXT_DB *db, char **row)
306
for (i=0; i<db->num_fields; i++)
308
if (db->index[i] != NULL)
310
if ((db->qual[i] != NULL) &&
311
(db->qual[i](row) == 0)) continue;
312
r=(char **)lh_retrieve(db->index[i],row);
315
db->error=DB_ERROR_INDEX_CLASH;
322
/* We have passed the index checks, now just append and insert */
323
if (!sk_push(db->data,(char *)row))
325
db->error=DB_ERROR_MALLOC;
329
for (i=0; i<db->num_fields; i++)
331
if (db->index[i] != NULL)
333
if ((db->qual[i] != NULL) &&
334
(db->qual[i](row) == 0)) continue;
335
lh_insert(db->index[i],row);
343
void TXT_DB_free(TXT_DB *db)
351
if (db->index != NULL)
353
for (i=db->num_fields-1; i>=0; i--)
354
if (db->index[i] != NULL) lh_free(db->index[i]);
355
OPENSSL_free(db->index);
357
if (db->qual != NULL)
358
OPENSSL_free(db->qual);
359
if (db->data != NULL)
361
for (i=sk_num(db->data)-1; i>=0; i--)
363
/* check if any 'fields' have been allocated
364
* from outside of the initial block */
365
p=(char **)sk_value(db->data,i);
366
max=p[db->num_fields]; /* last address */
367
if (max == NULL) /* new row */
369
for (n=0; n<db->num_fields; n++)
370
if (p[n] != NULL) OPENSSL_free(p[n]);
374
for (n=0; n<db->num_fields; n++)
376
if (((p[n] < (char *)p) || (p[n] > max))
381
OPENSSL_free(sk_value(db->data,i));