cgi_data.c File Reference

#include "cgi.h"

Include dependency graph for cgi_data.c:

Go to the source code of this file.

Functions

int SkipLines (FILE *in, size_t lines)
int DoesFileMatchForm (CGINameValue *data, CGINameValue *hdr)
CGINameValue_loaddbheader (FILE *f, int extra)
void WriteXML (FILE *f, CGINameValue *data)
int SaveDataToXML (CGINameValue *data, char *filename, int *pos)
int DatabaseOpen (char *filename, FILE **database, CGINameValue **header, int extra, int rw)
int DatabaseReset (FILE *database)
int DatabaseFFD (FILE *database, int skiprecords)
void ResetList (CGINameValue *v)
int DatabaseDeleteRecord (char *database, int record)
void UnfixQuotes (char *c)
void FixQuotes (CGINameValue *v)
int DatabaseReadRecord (FILE *database, CGINameValue *v, int *flags)
void WriteValue (HANDLE file, char *c)
int DatabaseSaveIndex (char *indexfile, CGINameValue *Params, int pos)
int DatabaseSaveNewRecord (char *filename, CGINameValue *v, int *pos)
void DatabaseClose (FILE *database, CGINameValue *header)
char * FindEndChar (char *text, char start, char finish)
int CreateDatabase (CGINameValue *data, char *filename)
int SaveDataToASC (CGINameValue *data, char *filename, int *pos)


Function Documentation

CGINameValue* _loaddbheader FILE *  f,
int  extra
 

record index starts with 1. record 0 refers to the header. A new array structure is returned. Remember to use

See also:
DeleteNVP

Definition at line 69 of file cgi_data.c.

References CGIFCLOSE, DeleteNVP(), MAXBUF, CGINameValue::name, NewNVP(), ReadUntilChar(), strdup(), and CGINameValue::value.

Referenced by DatabaseOpen().

00070 {
00071  char name[MAXBUF];
00072  int c;
00073  size_t x;
00074  size_t fieldcount = 0;
00075  CGINameValue*v, *i;
00076 
00077    do {
00078      c = ReadUntilChar(f,name,MAXBUF,"\t\n",'\r');
00079      fieldcount++;
00080 
00081      if (c == EOF) /* the header needs to be LF terminated! */
00082        {
00083         CGIFCLOSE(f);
00084         return 0;
00085        }
00086    } while (c != '\r' && c != '\n');
00087 
00088  if (fieldcount == 1 && *name == 0) return 0;
00089 
00090 /* create a structure to hold the values  */
00091  v = NewNVP(fieldcount+extra);
00092  i = v;
00093 
00094  for (x = fieldcount; x < fieldcount + extra; x++)
00095  {v[x].name = strdup(""); v[x].value = strdup(""); }
00096 
00097 /* reopen the file at the beginning       */
00098 #ifdef __WINCE__
00099  fseek(f,0,SEEK_SET);
00100 #else
00101  rewind(f);
00102 #endif
00103 
00104 /* read the fieldnames into the structure */
00105   do {
00106      char * d;
00107      c = ReadUntilChar(f,name,MAXBUF,"\t\n",'\r');
00108      d = strchr(name,'\r');
00109      if (d) *d = 0; /* just in case we opened it in binary mode */
00110 
00111      i->name = strdup((name[0] == '#') ? name+1 : name);
00112 
00113      i++;
00114      fieldcount --;
00115      if (c == EOF)
00116        {
00117         CGIFCLOSE(f);
00118         DeleteNVP(v);
00119         return 0;
00120        }
00121    } while (c != '\r' && c != '\n' && fieldcount);
00122 
00123  return v;
00124 }

int CreateDatabase CGINameValue data,
char *  filename
 

Definition at line 922 of file cgi_data.c.

References CGIFOPEN, CGINameValue::name, NULLSTR, and stricmp().

Referenced by SaveDataToASC().

00923 {
00924  char * lastfieldname=NULLSTR;
00925  register int x ;
00926  FILE* handle;
00927  char * c;
00928 
00929 /*File does not exist, so we save fieldnames. Appends to the data file*/
00930   handle=CGIFOPEN(filename,"ab+");
00931   if (handle ==0)
00932     {
00933      return 4;
00934     }
00935 
00936   for(x=0; data[x].name ; x++)
00937    {
00938     c = data[x].name;
00939     if (!*c) continue;
00940     if (stricmp(lastfieldname,c))
00941        {
00942         if (*lastfieldname) fwrite("\t",1,1,handle);
00943         fwrite(c,1,strlen(c),handle);
00944        }
00945     lastfieldname=c;
00946    }
00947   fwrite("\r\n",2,1,handle);
00948   CGIFCLOSE(handle); /* done! */
00949 return 0; /* success */
00950 }

void DatabaseClose FILE *  database,
CGINameValue header
 

Frees memory allocated for database and header, if non-null.

Definition at line 911 of file cgi_data.c.

References CGIFCLOSE, and DeleteNVP().

Referenced by CGImain(), DatabaseSaveIndex(), DatabaseSaveNewRecord(), JSHasRecord(), LoadUserDataASC(), and Login().

00912 {
00913  if (database) CGIFCLOSE(database);
00914  if (header) DeleteNVP(header);
00915 }

int DatabaseDeleteRecord char *  database,
int  record
 

Returns 0 on success. May return error code 15.

Definition at line 355 of file cgi_data.c.

References CGIFCLOSE, CGIFOPEN, and NULL.

00356 {/* can't use CGIFOPEN for writing, since it would truncate the data */
00357  char c;
00358  int count = 0;
00359 #ifdef __WINCE__
00360  FILE* f = CGIFOPEN(database,"r+");
00361 
00362  if (f == NULL) return 7;
00363 
00364  while (count < record)
00365   {
00366    if (fread(&c,1,1,f) != 1) {CGIFCLOSE(f); return 15;}
00367    if (c == '\n') count ++;
00368   }
00369 
00370  fread(&c,1,1,f);
00371  if (c == '\n') return 0; /* can't delete an empty row, sorry */
00372 
00373  fseek(f,-1,SEEK_CUR);
00374  if (fwrite("#",1,1,f) != 1) {CGIFCLOSE(f); return 15;}
00375  CGIFCLOSE(f);
00376 #else
00377  int f = open(database,O_RDWR);
00378 
00379  if (f < 0) return 7;
00380 
00381  while (count < record)
00382   {
00383    if (read(f,&c,1) != 1) {close(f); return 15;}
00384    if (c == '\n') count ++;
00385   }
00386 
00387  read(f,&c,1);
00388  if (c == '\n') return 0; /* can't delete an empty row, sorry */
00389 
00390  lseek(f,-1,SEEK_CUR);
00391  if (write(f,"#",1) != 1) { close(f);return 15;}
00392  close(f);
00393 #endif
00394  /* deletes a row from the database. Minor data loss. */
00395  /* if the first row is named STATUS, everything will work great! */
00396 
00397  return 0;
00398 }

int DatabaseFFD FILE *  database,
int  skiprecords
 

Definition at line 332 of file cgi_data.c.

References DatabaseReset(), and SkipLines().

Referenced by CGImain().

00333 {
00334  if (skiprecords < 0) return DatabaseReset(database);
00335  if (skiprecords == 0) return 0;
00336  return SkipLines(database,skiprecords);
00337 }

int DatabaseOpen char *  filename,
FILE **  database,
CGINameValue **  header,
int  extra,
int  rw
 

Definition at line 294 of file cgi_data.c.

References _loaddbheader(), CGIFCLOSE, CGIFOPEN, DATABASE, and NULL.

Referenced by CGImain(), DatabaseSaveIndex(), DatabaseSaveNewRecord(), EZSReport(), JSHasRecord(), LoadUserDataASC(), and Login().

00295 {
00296  /*char newname[MAXPATH]; */
00297  DATABASE * file;
00298  int ret;
00299 #ifdef __BORLANDC__
00300  file  = CGIFOPEN(filename,"rb+"); /* open a buffered file in text mode*/
00301 #else
00302  file  = CGIFOPEN(filename,rw ? "rb+" : "rb"); /* open a buffered file in text mode*/
00303 #endif
00304 
00305  if (database) { *database = file; }
00306 
00307  if (file == NULL)
00308   {
00309    if (header) *header = 0;
00310    ret = 0;
00311   }
00312  else
00313   {
00314    CGINameValue * v = _loaddbheader(file,extra);
00315    if (header) *header = v;
00316    ret = v ? 1 : 0;
00317    if (database == NULL) CGIFCLOSE(file);
00318  }
00319  return ret;
00320 }

int DatabaseReadRecord FILE *  database,
CGINameValue v,
int *  flags
 

When reading data, it uses FixQuotes() to remove leading/trailing quotes and convert doubled quotes to single quotes. The file pointer is advanced to the next record. v comes from DatabaseOpen().

Definition at line 449 of file cgi_data.c.

References CGIFREE, CGIMALLOC, FixQuotes(), MAXDATA, CGINameValue::name, NULL, ReadUntilChar(), ResetList(), strdup(), UnfixQuotes(), and CGINameValue::value.

Referenced by CGImain(), DatabaseFindFast(), DatabaseFindNextRecord(), LoadUserDataASC(), and PrintRecords().

00450 {
00451  int c = 0;
00452  char*d = 0;
00453  char *data = 0;
00454  int any = 0;
00455 
00456  data = CGIMALLOC(MAXDATA);
00457 
00458  if (flags) *flags = 0;
00459  if (data == NULL) return 0;
00460 
00461  ResetList(v); /* clear the record, just to be sure */
00462 
00463  do {
00464     if (v->name == NULL) /* end of header, but not end of line? */
00465      { /* finish off the line and continue */
00466        ReadUntilChar(database,0,0,"\n",0);
00467       break;
00468      }
00469     c = ReadUntilChar(database,data,MAXDATA,"\t\n",'\r');
00470 
00471     d = strchr(data,'\r');
00472     if (d != NULL) *d = 0; /* just in case we opened it in binary mode */
00473 
00474     if (any == 0 && flags != NULL)
00475      {
00476       switch (data[0])
00477       { case 0 :  *flags = 2; if (*data) if (strstr(data+1,"\"\t")) data[0]='\"'; break;
00478         case '#': *flags = 1; if (*data) if (strstr(data+1,"\"\t")) data[0]='\"'; break;
00479         default:   *flags = 0;
00480       }
00481      }
00482 
00483     if (*data)
00484      {
00485       v->value = strdup(data);
00486       if (v->value[0] == '\"')
00487        UnfixQuotes(v->value);
00488       any = 1;
00489      }
00490 
00491     v++;
00492 
00493     if (c == EOF ) /* premature end of file */
00494       {
00495        CGIFREE(data);
00496        if (any) FixQuotes(v);
00497        return any;
00498       }
00499    } while (c != '\n');
00500 
00501  CGIFREE(data);
00502  if (any) FixQuotes(v);
00503  return any;
00504 }

int DatabaseReset FILE *  database  ) 
 

Definition at line 322 of file cgi_data.c.

References SkipLines().

Referenced by DatabaseFFD().

00323 {
00324 #ifdef __WINCE__
00325  fseek(database,0,SEEK_SET);
00326 #else
00327  rewind(database);
00328 #endif
00329  return SkipLines(database,1);
00330 }

int DatabaseSaveIndex char *  indexfile,
CGINameValue Params,
int  pos
 

Definition at line 568 of file cgi_data.c.

References CGIFOPEN, DatabaseClose(), DatabaseOpen(), GetFieldValue, and NULL.

00569 {
00570     FILE * indexdb;
00571     CGINameValue * indexheader;
00572     int ret = 0;
00573 
00574     if (DatabaseOpen(indexfile,&indexdb,&indexheader,0,0))
00575     {
00576       FILE* ndx;
00577 
00578       DatabaseClose(indexdb,NULL);
00579       ndx = CGIFOPEN(indexfile,"ab");
00580       if (ndx)
00581       {
00582        size_t i;
00583        for ( i=0; indexheader[i].name; i++)
00584        {
00585         if (!strcmp(indexheader[i].name,"_POS"))
00586          { fprintf(ndx,"%d",pos); }
00587         else
00588          { fprintf(ndx,"\"%s\"\t",GetFieldValue(Params,indexheader[i].name)); }
00589        }
00590        fprintf(ndx,"\n");
00591        fclose(ndx);
00592       }
00593       else
00594        ret = 9;
00595 
00596       DatabaseClose(NULL,indexheader);
00597     }
00598     return ret;
00599  }

int DatabaseSaveNewRecord char *  filename,
CGINameValue v,
int *  pos
 

Uses WriteValue() to save data in a quoted, tab-delimited file. Linefeeds and newlines are removed, but data inside quotes can have tabs, and Excel 97 will read it fine.

Definition at line 605 of file cgi_data.c.

References BufferWriteL(), DatabaseClose(), DatabaseOpen(), MAXPATH, CGINameValue::name, NewBuffer(), NULLSTR, stricmp(), CGINameValue::value, and WriteValue().

Referenced by SaveDataToASC().

00606 {
00607  int x,y;
00608  CGINameValue * header;
00609  char *c, * lastfieldname;
00610  int ret = 0, writecomma;
00611 #ifdef XP_WIN
00612  HANDLE fh;
00613  DWORD written=0;
00614 #ifndef VPWSCGI
00615  HANDLE Mutex;
00616 #endif
00617 #else
00618  TextBuffer * buf;
00619  int fh;
00620  static struct flock myLock ;
00621 #endif
00622 
00623  if (!DatabaseOpen(filename,0,&header,0,0))
00624  {
00625   /*LogError("\nTried to read a data file, failed: ");
00626   LogError(filename);*/
00627   return 2;
00628  }
00629 
00630 /* do this early to minimize the time the file is open
00631  if (!DoesFileMatchForm(v, header)) ret = 5;
00632 */
00633 
00634 
00635 /* personal web server is single-threaded, no need for file locks */
00636 #if defined(XP_WIN) && !defined(VPWSCGI)
00637  {
00638 #ifdef UNICODE
00639  wchar_t Mutex_name[MAXPATH+1];
00640  ToWideChar(_filename,strlen(_filename),Mutex_name,MAXPATH);
00641 #else
00642  char Mutex_name[MAXPATH+1];
00643  strncpy(Mutex_name,filename,MAXPATH);
00644 #endif
00645  Mutex_name[MAXPATH] = 0;
00646  for (x=0; Mutex_name[x]; x++) if (Mutex_name[x] == '\\') Mutex_name[x] = '/';
00647  Mutex = CreateMutex(0,FALSE,Mutex_name);
00648 
00649  /* wait up to 20 seconds */
00650  if(Mutex) if ( WaitForSingleObject(Mutex,20000) == WAIT_TIMEOUT)
00651   {
00652    CloseHandle(Mutex);
00653    DatabaseClose(0,header);
00654    return 23;
00655   }
00656  }
00657 #endif
00658 
00659 #ifdef XP_WIN /* binary mode, direct write */
00660 
00661 #ifdef __WINCE__
00662  {
00663    wchar_t fn[MAXPATH+1];
00664    ToWideChar(filename,strlen(filename),fn,MAXPATH+1);
00665    fh = CreateFileW(fn,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
00666  }
00667 #else
00668  fh = CreateFileA(filename,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,0,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,0);
00669 #endif
00670 
00671  if (fh == INVALID_HANDLE_VALUE)
00672  {
00673 #if !defined(VPWSCGI)
00674    if (Mutex) CloseHandle(Mutex);
00675 #endif
00676      x = GetLastError();
00677     return 6;
00678  }
00679  x = SetFilePointer(fh,0,0,FILE_END);
00680 #else
00681  fh = open(filename,O_WRONLY|O_APPEND);
00682 
00683  if (fh == -1)
00684  {
00685   return 6;
00686  }
00687 #endif
00688 
00689 
00690 /* Wait for a file lock to become available */
00691 #ifdef XP_POSIX
00692     myLock.l_type = F_WRLCK ;
00693     myLock.l_start = 0 ;
00694     myLock.l_whence = SEEK_END ;
00695     myLock.l_len = 0 ;
00696     myLock.l_pid = getpid() ;
00697  fcntl(fh, F_SETLKW, &myLock);
00698 #endif
00699 
00700  if (pos)
00701  {
00702 #ifdef XP_WIN
00703   *pos = x;
00704 #else
00705   *pos = lseek(fh,0,SEEK_END);
00706 #endif
00707  }
00708 
00709 #ifndef XP_WIN
00710  buf = NewBuffer(16384);
00711 #endif
00712 
00713  for(x=0; header[x].name; x++)
00714    {
00715     /* if two consecutive questions have the same fieldname, append their data together */
00716     if (!header[x].name[0]) continue;
00717     /*don't write empty fieldnames */
00718 
00719 #ifdef XP_WIN
00720         WriteFile(fh,"\"",1,&written,0);
00721 #else
00722       BufferWriteL(buf,"\"",1);
00723 /*      write(fh,"\"",1); */
00724 #endif
00725     y = 0;
00726     lastfieldname = NULLSTR;
00727     writecomma = 0;
00728     while (v[y].name)
00729     {
00730      if (v[y].name[0] && stricmp(header[x].name,v[y].name)==0)
00731      {/*write this entry*/
00732        c = v[y].value;
00733        if ( c && *c )
00734         {
00735          if (*lastfieldname && writecomma)
00736 #ifdef XP_WIN
00737                 WriteFile(fh,",",1,&written,0);
00738          WriteValue(fh,c);
00739 #else
00740                 BufferWriteL(buf,",",1);
00741          WriteValue(buf,c);
00742             /* write(fh,",",1); WriteValue(fh,c); */
00743 #endif
00744          if (*c) writecomma = 1;
00745         }
00746       lastfieldname=header[x].name;
00747      }
00748      y++;
00749     }
00750 #ifdef XP_WIN
00751         WriteFile(fh,"\"\t",2,&written,0);
00752 #else
00753       BufferWriteL(buf,"\"\t",2);
00754         /*write(fh,"\"\t",2); */
00755 #endif
00756   }
00757 
00758 #ifdef XP_WIN
00759         WriteFile(fh,"\r\n",2,&written,0);
00760 #else
00761       BufferWriteL(buf,"\r\n",2);
00762         /*write(fh,"\r\n",2);*/
00763 #endif
00764 
00765 #if defined(XP_WIN) && !defined(VPWSCGI)
00766 if (Mutex)
00767 {
00768  ReleaseMutex(Mutex);
00769  CloseHandle(Mutex);
00770 }
00771 #endif
00772 
00773 #ifndef XP_WIN
00774  c = CopyBuffer(buf);
00775  x = lseek(fh,0,SEEK_END);
00776  if (pos) *pos = x;
00777  write(fh,c,BufferSize(buf));
00778  free(c);
00779  DeleteBuffer(buf);
00780 #endif
00781 
00782 #ifdef XP_POSIX
00783  myLock.l_type = F_UNLCK;
00784  fcntl(fh, F_SETLKW, &myLock);
00785 #endif
00786 
00787 #ifdef XP_WIN
00788  CloseHandle(fh);
00789 #else
00790  close(fh);
00791 #endif
00792 
00793  DatabaseClose(0,header);
00794  return ret;
00795 }

int DoesFileMatchForm CGINameValue data,
CGINameValue hdr
 

Writes any missing fields in the log file. Fields beginning with _ are ones that we add for our convenience and don't have to be saved.

Definition at line 42 of file cgi_data.c.

References GetField(), HasTokenI(), LogError(), and NULL.

00043 {
00044  int x;
00045  if (hdr == NULL) return 0;
00046  for (x=0; (data[x].name != NULL); x++)
00047   {
00048    if (data[x].name[0] == 0) continue;
00049    if (data[x].name[0] == '_') continue;
00050 
00051    if (HasTokenI("HOST,DATE,TIME",data[x].name,0)) continue;
00052    if (data[x].value == 0) continue;
00053    if (data[x].value[0] == 0) continue;
00054 
00055    /* don't require fields that we add to save */
00056    if (GetField(hdr, data[x].name) == NULL)
00057    {
00058     LogError("\nCGI_DATA: data file missing the field: ");
00059     LogError(data[x].name);
00060     return 0;
00061    }
00062   }
00063  return 1;
00064 }

char* FindEndChar char *  text,
char  start,
char  finish
 

Referenced by EvaluateAlgebra().

void FixQuotes CGINameValue v  ) 
 

Definition at line 421 of file cgi_data.c.

References NULL, and CGINameValue::value.

Referenced by DatabaseReadRecord().

00422 {
00423  int x;
00424  for (x=0; v[x].name; x++)
00425   {
00426    if (v[x].value == NULL) continue;
00427    if (v[x].value[0] == '\"')
00428      {
00429       int a=1,b=0;
00430       while (v[x].value[a])
00431        {
00432         v[x].value[b] = v[x].value[a];
00433         if (v[x].value[a] == '\"')
00434          {
00435           if (v[x].value[a+1] == '\"') a++;
00436           else break;
00437          }
00438 
00439         a++; b++;
00440        }
00441       v[x].value[b] = 0;
00442      }
00443   }
00444 }

void ResetList CGINameValue v  ) 
 

Definition at line 339 of file cgi_data.c.

References CGIFREE, CGINameValue::name, NULL, and CGINameValue::value.

Referenced by DatabaseReadRecord().

00340 {
00341  for (; v->name; v++)
00342   {
00343 #ifdef CGIFREE
00344     CGIFREE(v->value);
00345 #else
00346     if (v->value != NULL)
00347      {
00348       CGIFREE(v->value);
00349       v->value = NULL;
00350      }
00351 #endif
00352   }
00353 }

int SaveDataToASC CGINameValue data,
char *  filename,
int *  pos
 

Adds a new record to the database

Definition at line 952 of file cgi_data.c.

References CGIFCLOSE, CGIFOPEN, CreateDatabase(), and DatabaseSaveNewRecord().

00953 {
00954 #if 0
00955  int x;
00956  FILE* handle;
00957 
00958  /* Check to see if file exists*/
00959 
00960  handle=CGIFOPEN(filename,"rb");
00961  if ( handle == 0 )
00962   {
00963    x = CreateDatabase(data,filename);
00964    if (x) return x;
00965    /* that should ensure that the file exists, now open it in append mode*/
00966   }
00967  else
00968   {
00969    CGIFCLOSE(handle);
00970   }
00971 #endif
00972  return DatabaseSaveNewRecord(filename,data,pos);
00973 }

int SaveDataToXML CGINameValue data,
char *  filename,
int *  pos
 

Adds a new record to the database

Definition at line 198 of file cgi_data.c.

References CGIFCLOSE, CGIFOPEN, MAXPATH, NULL, swapchars(), and WriteXML().

00199 {
00200  FILE* f = NULL;
00201 #ifndef __WINCE__
00202  int fh;
00203 #endif
00204 #ifdef XP_POSIX
00205  static struct flock myLock ;
00206 #endif
00207 #if defined(XP_WIN) && !defined(VPWSCGI)
00208  HANDLE Mutex;
00209  char Mutex_name[MAXPATH+1];
00210 #endif
00211 
00212 /*
00213 #ifndef __WINCE__
00214  if (access(filename,2)) return 6;
00215 #endif
00216 */
00217 
00218 #if defined(XP_WIN) && !defined(VPWSCGI)
00219  strncpy(Mutex_name,filename,MAXPATH);
00220  Mutex_name[MAXPATH] = 0;
00221  swapchars(Mutex_name, '\\', '/');
00222 
00223  Mutex = CreateMutex(0,FALSE,Mutex_name);
00224 
00225  /* wait up to 20 seconds */
00226  if (Mutex) if (WaitForSingleObject(Mutex,20000) == WAIT_TIMEOUT)
00227   {
00228    CloseHandle(Mutex);
00229    return 23;
00230   }
00231 #endif
00232 
00233 #ifdef __WINCE__
00234  f = CGIFOPEN(filename,"ab");
00235 #else
00236  fh = open(filename,O_WRONLY|O_APPEND);
00237  if (fh != -1)
00238   {
00239    f = fdopen(fh,"ab");
00240   }
00241 #endif
00242 
00243  if (!f) return 8;
00244 
00245 /* Wait for a file lock to become available */
00246 #ifdef XP_POSIX
00247     myLock.l_type = F_WRLCK ;
00248     myLock.l_start = 0 ;
00249     myLock.l_whence = SEEK_END ;
00250     myLock.l_len = 0 ;
00251     myLock.l_pid = getpid() ;
00252  fcntl(fh, F_SETLKW, &myLock);
00253 #endif
00254 
00255 
00256  if (pos) *pos = ftell(f);
00257  WriteXML(f,data);
00258 
00259 #ifdef XP_POSIX
00260  myLock.l_type = F_UNLCK;
00261  fcntl(fh, F_SETLKW, &myLock);
00262 #endif
00263 
00264 #if defined(XP_WIN) && !defined(VPWSCGI)
00265 if (Mutex)
00266 {
00267  ReleaseMutex(Mutex);
00268  CloseHandle(Mutex);
00269  }
00270 #endif
00271 
00272  CGIFCLOSE(f);
00273  return 0;
00274 }

int SkipLines FILE *  in,
size_t  lines
 

Definition at line 26 of file cgi_data.c.

Referenced by DatabaseFFD(), and DatabaseReset().

00027 {
00028  char c;
00029  int skipped =0;
00030  while (lines && fread(&c,1,1,in)>0 )
00031  {
00032   if (c == '\n') {lines--; skipped++;}
00033  }
00034  if (lines) return 0;
00035  return skipped;
00036 }

void UnfixQuotes char *  c  ) 
 

Definition at line 400 of file cgi_data.c.

Referenced by DatabaseReadRecord().

00401 {
00402  char * d = c;
00403 
00404  if (!strcmp(c,"\"\""))
00405   {
00406    c[0] = 0;
00407    return;
00408   }
00409 
00410  while (*c)
00411  {
00412   if (c[0] == '\"') c++;
00413   *d = *c;
00414   d++;
00415   if (*c) c++;
00416  }
00417 
00418 }

void WriteValue HANDLE  file,
char *  c
 

Quotes get doubled and linefeeds ge stripped

Definition at line 508 of file cgi_data.c.

Referenced by DatabaseSaveNewRecord().

00509 {
00510  size_t len;
00511  DWORD written=0;
00512  while (*c)
00513   {
00514    if (*c == '\"') WriteFile(file,"\"",1,&written,0);
00515 
00516    if (*c != '\n' && *c != '\r')
00517    {
00518       len = strcspn(c+1,"\"");
00519       WriteFile(file,c,1+len,&written,0);
00520       c += len;
00521    }
00522 
00523    c++;
00524   }
00525 }

void WriteXML FILE *  f,
CGINameValue data
 

Generates an XML TRANSACTION tag from data. Links are expected to be seen as parentfield_number_childfield

Definition at line 127 of file cgi_data.c.

References CGIFREE, CGINameValue::name, NULL, strdup(), and stricmp().

Referenced by SaveDataToXML().

00128 {
00129  int i;
00130  char * currentchild = NULL;
00131  int currentitem = -1;
00132 
00133  fprintf(f,"<TRANSACTION>");
00134 
00135  for(i=0;data[i].name;i++) /* skip host, date, time */
00136   {
00137    char * c;
00138    int inchild = 0;
00139    char* name;
00140    if (!data[i].name[0]) continue;
00141    if (data[i].name[0] == '_') continue;
00142 
00143    name = data[i].name;
00144    c = strchr(name,'_');
00145 
00146    if (c)
00147     if (strchr(c+2,'_'))
00148      if (strchr("1234567890",c[1])) /* item_1_name */
00149       {
00150        int thisitem;
00151        int newobj = 0;
00152        char* newchild = strdup(name);
00153 
00154        inchild = 1;
00155        c = strchr(newchild,'_');
00156 
00157        thisitem = atoi(c+1);
00158 
00159        name = strchr(c+2,'_');
00160        if (name) name++;
00161 
00162        c[0] = 0;
00163 
00164        if (thisitem != currentitem || stricmp(currentchild,newchild))
00165        {
00166         newobj = 1;
00167         currentitem = thisitem;
00168        }
00169 
00170        if (newobj && currentchild) fprintf(f,"</%s>\n",currentchild);
00171 
00172        if (name)
00173     {
00174      if (currentchild) CGIFREE(currentchild);
00175          currentchild = newchild;
00176          if (newobj) fprintf(f,"<%s id=%d>\n",currentchild,thisitem);
00177         }
00178        else name=data[1].name;
00179       }
00180 
00181    if (inchild == 0 && currentchild)
00182      {
00183        fprintf(f,"</%s>\n",currentchild);
00184        if (currentchild) CGIFREE(currentchild);
00185        currentchild = NULL;
00186 
00187      }
00188 
00189    fprintf(f,"<%s>%s</%s>\n",name,data[i].value,name);
00190 
00191   }
00192 
00193  if (currentchild) printf("</%s>\n",currentchild);
00194  if (currentchild) CGIFREE(currentchild);
00195  fprintf(f,"</TRANSACTION>\n");
00196 }



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/