cgi_search.c

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /* cgi_search.c © Copyright 1998-2005 by Raosoft Inc. All Rights Reserved.    */
00003 /*                                                                            */
00004 /* You may use and modify this file for your own use, but may not distribute  */
00005 /* it or derivative works without the prior written consent of Raosoft, Inc.  */
00006 /*                                                                            */
00007 /* If you choose to share your modifications with Raosoft, Inc. the company   */
00008 /* will attempt to incorporate them into future versions of this file.        */
00009 /*                                                                            */
00010 /* This software is provided "as is," and Raosoft makes no warranty, express  */
00011 /* or implied, of fitness for a particular application. Every measure has been*/
00012 /* taken to anticipate risks inherent to computer networks, but we cannot     */
00013 /* guarantee safety or reliability of this program in every situation.        */
00014 /*                                                                            */
00015 /******************************************************************************/
00016 
00017 #include "cgi.h"
00018 
00019 #ifndef XP_WIN
00020 #ifndef AIX3
00021 #include <sys/file.h>
00022 #endif
00023 
00024 #endif
00025 
00026 char * strn2istr(char *s1, char *s2,size_t l2);
00027 
00028 char * stristr(char *s1, char *s2);
00029 
00030 /* the new way of doing it */
00031 int DatabaseFindNextRecord(DATABASE * database,
00032                            CGINameValue* header,
00033                            CGINameValue* cgidata,
00034                            char* query)
00035 {
00036  int ret = 0;
00037  char * Comparison = strdup(query);
00038 
00039  while (1)
00040    {
00041     int flags = 0;
00042 
00043     if (DatabaseReadRecord(database, header,&flags) == 0) break;
00044     if (flags != 0) continue; /* indicates a deleted record */
00045 
00046     if (query == NULL) {ret = 1; break;}
00047 
00048     if (EvaluateLogic(Comparison,header,cgidata)) {ret = 1; break;}
00049     strcpy(Comparison,query);
00050   }
00051  CGIFREE(Comparison);
00052  return ret; /* ran out */
00053 }
00054 
00055 int Matches(CGINameValue* header,
00056                      CGINameValue* query)
00057 {
00058  int x;
00059 
00060     for (x=0; query[x].name != NULL ;x++)
00061     {
00062      CGINameValue* f;
00063      if (!query[x].name[0]) continue;
00064      f = GetField(header,query[x].name);
00065      if (!f) continue;
00066      if (strcmp(f->value?f->value:"",query[x].value)) return 0;
00067     }
00068 
00069     return 1; /* ha! found it */
00070 }
00071 
00072 int DatabaseFindFast(DATABASE * database,
00073                      CGINameValue* header,
00074                      CGINameValue* query,int* pos)
00075 {
00076  while (1)
00077    {
00078     int flags = 0;
00079     if (pos) *pos = ftell(database);
00080     if (DatabaseReadRecord(database, header,&flags) == 0) break;
00081     if (flags != 0) continue; /* indicates a deleted record */
00082 
00083     if (query == NULL) return 1;
00084 
00085     if (Matches(header,query)) return 1;
00086    }
00087  return 0; /* ran out */
00088 }
00089 
00090 #if 0 /* the old way of doing it */
00091 int DatabaseFindNextRecord(DATABASE * database,
00092                            CGINameValue* header,
00093                            CGINameValue* query,
00094                            int cs)
00095 {
00096  while (1)
00097    {
00098     int flags = 0;
00099     if (DatabaseReadRecord(database, header,&flags) == 0) break;
00100     if (flags != 0) continue; /* indicates a deleted record */
00101 
00102     if (query == NULL) return 1;
00103     if (DatabaseEvalQuery(header,query,cs)) return 1;
00104   }
00105  return 0; /* ran out */
00106 }
00107 
00108 int QueryCompare(char* data, char* compare, int cs)
00109 /* use SQL-style comparisons: _ is regex(.), % is regex(.*) */
00110 /* comparsions are not case sensitive */
00111  {
00112   int i=0;
00113   while (data[i] && compare[i])
00114    {
00115     if (cs)
00116      {
00117       if (data[i] == compare[i]) {i++;  continue;}
00118      }
00119     else
00120      {
00121       if (toupper(data[i]) == toupper(compare[i])) {i++; continue;}
00122      }
00123     if (compare[i] == '_' || compare[i] == '?') {i++; continue;}
00124     if (compare[i] == '%' || compare[i] == '*') return 1;
00125     return 0;
00126    }
00127 
00128   if ((data[i] == 0)
00129        && (compare[i] == '%' || compare[i] == '*' || compare[i] == 0))
00130        return 1;
00131   /* wildcard match or the strings are at their ends */
00132   return 0;
00133 
00134  }
00135 
00136 int DatabaseEvalQuery(CGINameValue* header, CGINameValue* query, int cs)
00137 {
00138  int x;
00139  char* c;
00140  if (query == NULL) return 1; /* anything goes */
00141 
00142     for (x=0; query[x].name != NULL ;x++)
00143     {
00144      if (!query[x].name[0]) continue;
00145      if (query[x].name[0] == '_') continue;
00146 
00147      c = GetFieldValue(header, query[x].name);
00148 
00149      if (!QueryCompare(c,query[x].value,cs)) return 0;
00150     }
00151 
00152     return 1; /* ha! found it */
00153 }
00154 #endif
00155 
00156 int DatabaseSearchRecord(DATABASE * database, char * querystr, int casesensitive)
00157 {
00158  int c;
00159  char *name = malloc(MAXDATA);
00160  long int fpos;
00161  int column=0;
00162 
00163  fpos = ftell(database);
00164  if (fpos < 0)
00165   {
00166    CGIFREE(name);
00167    return -1;
00168   }
00169  do {
00170     c = ReadUntilChar(database,name,MAXDATA,"\t\n",'\r');
00171     if (column++ == 0 && name[0] == '#')
00172      { /* skip comment lines and deleted records */
00173       ReadUntilChar(database,name,MAXDATA,"\n",'\r');
00174       CGIFREE(name);
00175       return 0;
00176      }
00177 
00178     if (name[0] == 0)  continue; /* skip blank fields */
00179     if (casesensitive)
00180      {
00181       if (strstr(name,querystr))
00182        {
00183         fseek(database,fpos,0);
00184         CGIFREE(name);
00185         return 1;
00186        }
00187      }
00188     else
00189      {
00190       if (stristr(name,querystr))
00191        {
00192         fseek(database,fpos,0);
00193         CGIFREE(name);
00194         return 1;
00195        }
00196      }
00197    } while (c != '\r' && c != '\n' && c != EOF);
00198 
00199  CGIFREE(name);
00200  return 0;
00201 }


Raosoft, Inc.
Raosoft EZReport, EZSurvey, InterForm, RapidReport, Raosoft, and SurveyWin are registered trademarks of Raosoft, Inc. Page contents © 1996-2007 by Raosoft, Inc. You may use and modify this file for your own use, but may not distribute it or derivative works without the prior written consent of Raosoft, Inc. This software is provided "as is," and Raosoft makes no warranty, express or implied, of fitness for a particular application. Every measure has been taken to anticipate risks inherent to computer networks, but we cannot guarantee safety or reliability of this program in every situation.
Tel: 206-525-4025 (US) Email: raosoft@raosoft.com
http://www.raosoft.com/