1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ssl/libcrypto/src/crypto/txt_db/txt_db.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,386 @@
1.4 +/* crypto/txt_db/txt_db.c */
1.5 +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
1.6 + * All rights reserved.
1.7 + *
1.8 + * This package is an SSL implementation written
1.9 + * by Eric Young (eay@cryptsoft.com).
1.10 + * The implementation was written so as to conform with Netscapes SSL.
1.11 + *
1.12 + * This library is free for commercial and non-commercial use as long as
1.13 + * the following conditions are aheared to. The following conditions
1.14 + * apply to all code found in this distribution, be it the RC4, RSA,
1.15 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
1.16 + * included with this distribution is covered by the same copyright terms
1.17 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1.18 + *
1.19 + * Copyright remains Eric Young's, and as such any Copyright notices in
1.20 + * the code are not to be removed.
1.21 + * If this package is used in a product, Eric Young should be given attribution
1.22 + * as the author of the parts of the library used.
1.23 + * This can be in the form of a textual message at program startup or
1.24 + * in documentation (online or textual) provided with the package.
1.25 + *
1.26 + * Redistribution and use in source and binary forms, with or without
1.27 + * modification, are permitted provided that the following conditions
1.28 + * are met:
1.29 + * 1. Redistributions of source code must retain the copyright
1.30 + * notice, this list of conditions and the following disclaimer.
1.31 + * 2. Redistributions in binary form must reproduce the above copyright
1.32 + * notice, this list of conditions and the following disclaimer in the
1.33 + * documentation and/or other materials provided with the distribution.
1.34 + * 3. All advertising materials mentioning features or use of this software
1.35 + * must display the following acknowledgement:
1.36 + * "This product includes cryptographic software written by
1.37 + * Eric Young (eay@cryptsoft.com)"
1.38 + * The word 'cryptographic' can be left out if the rouines from the library
1.39 + * being used are not cryptographic related :-).
1.40 + * 4. If you include any Windows specific code (or a derivative thereof) from
1.41 + * the apps directory (application code) you must include an acknowledgement:
1.42 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1.43 + *
1.44 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1.45 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1.46 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1.47 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1.48 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1.49 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1.50 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1.51 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1.52 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1.53 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1.54 + * SUCH DAMAGE.
1.55 + *
1.56 + * The licence and distribution terms for any publically available version or
1.57 + * derivative of this code cannot be changed. i.e. this code cannot simply be
1.58 + * copied and put under another distribution licence
1.59 + * [including the GNU Public Licence.]
1.60 + */
1.61 +
1.62 +#include <stdio.h>
1.63 +#include <stdlib.h>
1.64 +#include <string.h>
1.65 +#include "cryptlib.h"
1.66 +#include <openssl/buffer.h>
1.67 +#include <openssl/txt_db.h>
1.68 +
1.69 +#undef BUFSIZE
1.70 +#define BUFSIZE 512
1.71 +
1.72 +const char TXT_DB_version[]="TXT_DB" OPENSSL_VERSION_PTEXT;
1.73 +
1.74 +EXPORT_C TXT_DB *TXT_DB_read(BIO *in, int num)
1.75 + {
1.76 + TXT_DB *ret=NULL;
1.77 + int er=1;
1.78 + int esc=0;
1.79 + long ln=0;
1.80 + int i,add,n;
1.81 + int size=BUFSIZE;
1.82 + int offset=0;
1.83 + char *p,**pp,*f;
1.84 + BUF_MEM *buf=NULL;
1.85 +
1.86 + if ((buf=BUF_MEM_new()) == NULL) goto err;
1.87 + if (!BUF_MEM_grow(buf,size)) goto err;
1.88 +
1.89 + if ((ret=(TXT_DB *)OPENSSL_malloc(sizeof(TXT_DB))) == NULL)
1.90 + goto err;
1.91 + ret->num_fields=num;
1.92 + ret->index=NULL;
1.93 + ret->qual=NULL;
1.94 + if ((ret->data=sk_new_null()) == NULL)
1.95 + goto err;
1.96 + if ((ret->index=(LHASH **)OPENSSL_malloc(sizeof(LHASH *)*num)) == NULL)
1.97 + goto err;
1.98 + if ((ret->qual=(int (**)(char **))OPENSSL_malloc(sizeof(int (**)(char **))*num)) == NULL)
1.99 + goto err;
1.100 + for (i=0; i<num; i++)
1.101 + {
1.102 + ret->index[i]=NULL;
1.103 + ret->qual[i]=NULL;
1.104 + }
1.105 +
1.106 + add=(num+1)*sizeof(char *);
1.107 + buf->data[size-1]='\0';
1.108 + offset=0;
1.109 + for (;;)
1.110 + {
1.111 + if (offset != 0)
1.112 + {
1.113 + size+=BUFSIZE;
1.114 + if (!BUF_MEM_grow_clean(buf,size)) goto err;
1.115 + }
1.116 + buf->data[offset]='\0';
1.117 + BIO_gets(in,&(buf->data[offset]),size-offset);
1.118 + ln++;
1.119 + if (buf->data[offset] == '\0') break;
1.120 + if ((offset == 0) && (buf->data[0] == '#')) continue;
1.121 + i=strlen(&(buf->data[offset]));
1.122 + offset+=i;
1.123 + if (buf->data[offset-1] != '\n')
1.124 + continue;
1.125 + else
1.126 + {
1.127 + buf->data[offset-1]='\0'; /* blat the '\n' */
1.128 + if (!(p=(char *)OPENSSL_malloc(add+offset))) goto err;
1.129 + offset=0;
1.130 + }
1.131 + pp=(char **)p;
1.132 + p+=add;
1.133 + n=0;
1.134 + pp[n++]=p;
1.135 + i=0;
1.136 + f=buf->data;
1.137 +
1.138 + esc=0;
1.139 + for (;;)
1.140 + {
1.141 + if (*f == '\0') break;
1.142 + if (*f == '\t')
1.143 + {
1.144 + if (esc)
1.145 + p--;
1.146 + else
1.147 + {
1.148 + *(p++)='\0';
1.149 + f++;
1.150 + if (n >= num) break;
1.151 + pp[n++]=p;
1.152 + continue;
1.153 + }
1.154 + }
1.155 + esc=(*f == '\\');
1.156 + *(p++)= *(f++);
1.157 + }
1.158 + *(p++)='\0';
1.159 + if ((n != num) || (*f != '\0'))
1.160 + {
1.161 +#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) /* temporaty fix :-( */
1.162 + fprintf(stderr,"wrong number of fields on line %ld (looking for field %d, got %d, '%s' left)\n",ln,num,n,f);
1.163 +#endif
1.164 + er=2;
1.165 + goto err;
1.166 + }
1.167 + pp[n]=p;
1.168 + if (!sk_push(ret->data,(char *)pp))
1.169 + {
1.170 +#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) /* temporaty fix :-( */
1.171 + fprintf(stderr,"failure in sk_push\n");
1.172 +#endif
1.173 + er=2;
1.174 + goto err;
1.175 + }
1.176 + }
1.177 + er=0;
1.178 +err:
1.179 + BUF_MEM_free(buf);
1.180 + if (er)
1.181 + {
1.182 +#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)
1.183 + if (er == 1) fprintf(stderr,"OPENSSL_malloc failure\n");
1.184 +#endif
1.185 + if (ret != NULL)
1.186 + {
1.187 + if (ret->data != NULL) sk_free(ret->data);
1.188 + if (ret->index != NULL) OPENSSL_free(ret->index);
1.189 + if (ret->qual != NULL) OPENSSL_free(ret->qual);
1.190 + if (ret != NULL) OPENSSL_free(ret);
1.191 + }
1.192 + return(NULL);
1.193 + }
1.194 + else
1.195 + return(ret);
1.196 + }
1.197 +
1.198 +EXPORT_C char **TXT_DB_get_by_index(TXT_DB *db, int idx, char **value)
1.199 + {
1.200 + char **ret;
1.201 + LHASH *lh;
1.202 +
1.203 + if (idx >= db->num_fields)
1.204 + {
1.205 + db->error=DB_ERROR_INDEX_OUT_OF_RANGE;
1.206 + return(NULL);
1.207 + }
1.208 + lh=db->index[idx];
1.209 + if (lh == NULL)
1.210 + {
1.211 + db->error=DB_ERROR_NO_INDEX;
1.212 + return(NULL);
1.213 + }
1.214 + ret=(char **)lh_retrieve(lh,value);
1.215 + db->error=DB_ERROR_OK;
1.216 + return(ret);
1.217 + }
1.218 +
1.219 +EXPORT_C int TXT_DB_create_index(TXT_DB *db, int field, int (*qual)(char **),
1.220 + LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp)
1.221 + {
1.222 + LHASH *idx;
1.223 + char **r;
1.224 + int i,n;
1.225 +
1.226 + if (field >= db->num_fields)
1.227 + {
1.228 + db->error=DB_ERROR_INDEX_OUT_OF_RANGE;
1.229 + return(0);
1.230 + }
1.231 + if ((idx=lh_new(hash,cmp)) == NULL)
1.232 + {
1.233 + db->error=DB_ERROR_MALLOC;
1.234 + return(0);
1.235 + }
1.236 + n=sk_num(db->data);
1.237 + for (i=0; i<n; i++)
1.238 + {
1.239 + r=(char **)sk_value(db->data,i);
1.240 + if ((qual != NULL) && (qual(r) == 0)) continue;
1.241 + if ((r=lh_insert(idx,r)) != NULL)
1.242 + {
1.243 + db->error=DB_ERROR_INDEX_CLASH;
1.244 + db->arg1=sk_find(db->data,(char *)r);
1.245 + db->arg2=i;
1.246 + lh_free(idx);
1.247 + return(0);
1.248 + }
1.249 + }
1.250 + if (db->index[field] != NULL) lh_free(db->index[field]);
1.251 + db->index[field]=idx;
1.252 + db->qual[field]=qual;
1.253 + return(1);
1.254 + }
1.255 +
1.256 +EXPORT_C long TXT_DB_write(BIO *out, TXT_DB *db)
1.257 + {
1.258 + long i,j,n,nn,l,tot=0;
1.259 + char *p,**pp,*f;
1.260 + BUF_MEM *buf=NULL;
1.261 + long ret= -1;
1.262 +
1.263 + if ((buf=BUF_MEM_new()) == NULL)
1.264 + goto err;
1.265 + n=sk_num(db->data);
1.266 + nn=db->num_fields;
1.267 + for (i=0; i<n; i++)
1.268 + {
1.269 + pp=(char **)sk_value(db->data,i);
1.270 +
1.271 + l=0;
1.272 + for (j=0; j<nn; j++)
1.273 + {
1.274 + if (pp[j] != NULL)
1.275 + l+=strlen(pp[j]);
1.276 + }
1.277 + if (!BUF_MEM_grow_clean(buf,(int)(l*2+nn))) goto err;
1.278 +
1.279 + p=buf->data;
1.280 + for (j=0; j<nn; j++)
1.281 + {
1.282 + f=pp[j];
1.283 + if (f != NULL)
1.284 + for (;;)
1.285 + {
1.286 + if (*f == '\0') break;
1.287 + if (*f == '\t') *(p++)='\\';
1.288 + *(p++)= *(f++);
1.289 + }
1.290 + *(p++)='\t';
1.291 + }
1.292 + p[-1]='\n';
1.293 + j=p-buf->data;
1.294 + if (BIO_write(out,buf->data,(int)j) != j)
1.295 + goto err;
1.296 + tot+=j;
1.297 + }
1.298 + ret=tot;
1.299 +err:
1.300 + if (buf != NULL) BUF_MEM_free(buf);
1.301 + return(ret);
1.302 + }
1.303 +
1.304 +EXPORT_C int TXT_DB_insert(TXT_DB *db, char **row)
1.305 + {
1.306 + int i;
1.307 + char **r;
1.308 +
1.309 + for (i=0; i<db->num_fields; i++)
1.310 + {
1.311 + if (db->index[i] != NULL)
1.312 + {
1.313 + if ((db->qual[i] != NULL) &&
1.314 + (db->qual[i](row) == 0)) continue;
1.315 + r=(char **)lh_retrieve(db->index[i],row);
1.316 + if (r != NULL)
1.317 + {
1.318 + db->error=DB_ERROR_INDEX_CLASH;
1.319 + db->arg1=i;
1.320 + db->arg_row=r;
1.321 + goto err;
1.322 + }
1.323 + }
1.324 + }
1.325 + /* We have passed the index checks, now just append and insert */
1.326 + if (!sk_push(db->data,(char *)row))
1.327 + {
1.328 + db->error=DB_ERROR_MALLOC;
1.329 + goto err;
1.330 + }
1.331 +
1.332 + for (i=0; i<db->num_fields; i++)
1.333 + {
1.334 + if (db->index[i] != NULL)
1.335 + {
1.336 + if ((db->qual[i] != NULL) &&
1.337 + (db->qual[i](row) == 0)) continue;
1.338 + lh_insert(db->index[i],row);
1.339 + }
1.340 + }
1.341 + return(1);
1.342 +err:
1.343 + return(0);
1.344 + }
1.345 +
1.346 +EXPORT_C void TXT_DB_free(TXT_DB *db)
1.347 + {
1.348 + int i,n;
1.349 + char **p,*max;
1.350 +
1.351 + if(db == NULL)
1.352 + return;
1.353 +
1.354 + if (db->index != NULL)
1.355 + {
1.356 + for (i=db->num_fields-1; i>=0; i--)
1.357 + if (db->index[i] != NULL) lh_free(db->index[i]);
1.358 + OPENSSL_free(db->index);
1.359 + }
1.360 + if (db->qual != NULL)
1.361 + OPENSSL_free(db->qual);
1.362 + if (db->data != NULL)
1.363 + {
1.364 + for (i=sk_num(db->data)-1; i>=0; i--)
1.365 + {
1.366 + /* check if any 'fields' have been allocated
1.367 + * from outside of the initial block */
1.368 + p=(char **)sk_value(db->data,i);
1.369 + max=p[db->num_fields]; /* last address */
1.370 + if (max == NULL) /* new row */
1.371 + {
1.372 + for (n=0; n<db->num_fields; n++)
1.373 + if (p[n] != NULL) OPENSSL_free(p[n]);
1.374 + }
1.375 + else
1.376 + {
1.377 + for (n=0; n<db->num_fields; n++)
1.378 + {
1.379 + if (((p[n] < (char *)p) || (p[n] > max))
1.380 + && (p[n] != NULL))
1.381 + OPENSSL_free(p[n]);
1.382 + }
1.383 + }
1.384 + OPENSSL_free(sk_value(db->data,i));
1.385 + }
1.386 + sk_free(db->data);
1.387 + }
1.388 + OPENSSL_free(db);
1.389 + }