source: rtems/cpukit/httpd/emfdb.c @ a6b4c0df

4.104.114.84.95
Last change on this file since a6b4c0df was a6b4c0df, checked in by Joel Sherrill <joel.sherrill@…>, on 09/01/00 at 10:57:21

2000-08-30 Joel Sherrill <joel@…>

  • Merged version 2.1 of GoAhead? webserver. This update was submitted by Antti P Miettinen <antti.p.miettinen@…>.
  • NOTES, base64.c, ejIntrn.h, emfdb.c, emfdb.h, md5.h, md5c.c, um.c, um.h: New files.
  • wbase64.c: Removed.
  • Makefile.am, asp.c, balloc.c, default.c, ej.h, ejlex.c, ejparse.c, form.c, h.c, handler.c, mime.c, misc.c, ringq.c, rom.c, security.c, socket.c, sym.c, uemf.c, uemf.h, url.c, value.c, webcomp.c, webmain.c, webpage.c, webrom.c, webs.c, webs.h, websuemf.c, wsIntrn.h: Modified.
  • Property mode set to 100644
File size: 22.0 KB
RevLine 
[a6b4c0df]1/*
2 * emfdb.c -- EMF database compatability functions for GoAhead WebServer.
3 *
4 * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
5 *
6 * See the file "license.txt" for usage and redistribution license requirements
7 *
8 * $Id$
9 */
10
11/******************************** Description *********************************/
12/*
13 *      Textfile-based database support for WebServer 2.1.
14 */
15
16/********************************* Includes ***********************************/
17
18#include        "emfdb.h"
19#include        "wsIntrn.h"
20
21/********************************* Defines ************************************/
22
23#define KEYWORD_TABLE   T("TABLE")
24#define KEYWORD_ROW             T("ROW")
25
26/*********************************** Locals ***********************************/
27
28/*
29 *      Variable to support the basicSet and basicGet functions.
30 */
31
32static char_t   *basicProdDir = NULL;           
33static char_t   *basicDefaultDir = T("."); /* Default set to current */
34
35/*
36 * hAlloc chain list of table schemas to be closed
37 */
38
39static int                      dbMaxTables = 0;
40static dbTable_t        **dbListTables = NULL;
41
42/****************************** Forward Declarations **************************/
43
44static int              crack(char_t *buf, char_t **key, char_t **val);
45static char_t   *trim(char_t *str);
46static int              GetColumnIndex(int tid, char_t *colName);
47
48/******************************************************************************/
49/*
50 *      Add a schema to the module-internal schema database
51 */
52
53int dbRegisterDBSchema(dbTable_t *pTableRegister)
54{
55        dbTable_t       *pTable;
56        int                     tid;
57
58        a_assert(pTableRegister);
59
60        trace(4, T("DB: Registering database table <%s>\n"),
61                pTableRegister->name);
62
63/*
64 *      Bump up the size of the table array
65 */
66        tid = hAllocEntry((void***) &dbListTables,
67                &dbMaxTables, sizeof(dbTable_t));       
68
69/*
70 *      Copy the table schema to the last spot in schema array
71 */
72        a_assert(dbListTables);
73        pTable = dbListTables[tid];
74        a_assert(pTable);
75
76/*
77 *      Copy the name of the table
78 */
79        pTable->name = bstrdup(B_L, pTableRegister->name);
80
81/*
82 *      Copy the number of columns
83 */
84        pTable->nColumns = pTableRegister->nColumns;
85
86/*
87 *      Copy the column definitions
88 */
89        if (pTable->nColumns > 0) {
90                int i;
91                pTable->columnNames = balloc(B_L, sizeof(char_t *) * pTable->nColumns);
92                pTable->columnTypes = balloc(B_L, sizeof(int *) * pTable->nColumns);
93
94                for (i = 0; (i < pTableRegister->nColumns); i++) {
95                        pTable->columnNames[i] =
96                                bstrdup(B_L, pTableRegister->columnNames[i]);
97                        pTable->columnTypes[i] = pTableRegister->columnTypes[i];
98                }
99
100        } else {
101                pTable->columnNames = NULL;
102                pTable->columnTypes = NULL;
103        }
104
105/*
106 *      Zero out the table's data (very important!)
107 */
108        pTable->nRows = 0;
109        pTable->rows = NULL;
110
111        return 0;
112}
113
114/******************************************************************************/
115/*
116 *      This is provided for compatibility with EMF.  Tables are "registered"
117 *      with staticly defined schemas.  There is only one did in this package: 0.
118 */
119
120int dbOpen(char_t *tablename, char_t *filename,
121                   int (*gettime)(int did), int flags)
122{
123        basicProdDir = NULL;           
124        basicDefaultDir = T(".");
125        dbMaxTables = 0;
126        dbListTables = NULL;
127        return 0;
128}
129
130/******************************************************************************/
131/*
132 *      Delete all the rows of the tables, and all of the tables
133 */
134
135void dbClose(int did)
136{
137        int                     table, column;
138        dbTable_t       *pTable;
139
140/*
141 *      Before doing anything, delete all the contents of the database
142 */
143        dbZero(did);
144
145/*
146 *      Now delete the tables
147 */
148        for (table = 0; table < dbMaxTables; table++) {
149                pTable = dbListTables[table];
150
151                if (pTable != NULL) {
152/*
153 *                      Delete the table schema
154 */
155                        if (pTable->nColumns) {
156                                for (column = 0; column < pTable->nColumns; column++) {
157                                        bfreeSafe(B_L, pTable->columnNames[column]);
158                                }
159                                bfreeSafe(B_L, pTable->columnNames);
160                                bfreeSafe(B_L, pTable->columnTypes);
161                        }
162/*
163 *                      Delete the table name
164 */
165                        bfreeSafe(B_L, pTable->name);
166/*
167 *                      Free the table
168 */
169                        bfreeSafe(B_L, pTable);
170                        hFree((void ***) &dbListTables, table);
171                }
172        }
173
174        if (dbListTables) {
175                bfree(B_L, dbListTables);
176        }
177
178/*
179 *      Set the global table list to a safe value
180 */
181        dbListTables = NULL;
182        dbMaxTables = 0;
183}
184
185
186/******************************************************************************/
187/*
188 *      Delete all the data records in all tables
189 */
190
191void dbZero(int did)
192{
193        int                     table, row, column, nRows, nColumns;
194        int                     *pRow;
195        dbTable_t       *pTable;
196
197/*
198 *      Delete all data from all tables
199 */
200        for (table = 0; table < dbMaxTables; table++) {
201                pTable = dbListTables[table];
202/*
203 *              Delete the row data contained within the schema
204 */
205                if (pTable) {
206                        nColumns = pTable->nColumns;
207                        nRows = pTable->nRows;
208                        for (row = 0; row < nRows; row++) {
209                                pRow = pTable->rows[row];
210                                if (pRow) {
211/*
212 *                                      Only delete the contents of rows not previously deleted!
213 */
214                                        for (column = 0; column < nColumns; column++) {
215                                                if (pTable->columnTypes[column] == T_STRING) {
216                                                        bfreeSafe(B_L, (char_t *)(pRow[column]));
217                                                        pRow[column] = (int)NULL;
218                                                }
219                                        }
220
221                                        bfreeSafe(B_L, pRow);
222                                        hFree((void ***) &pTable->rows, row);
223                                }
224                        }
225
226                        pTable->rows = NULL;
227                        pTable->nRows = 0;
228                }
229        }
230}
231
232/******************************************************************************/
233/*
234 *      Find the a row in the table with the given string in the given column
235 */
236
237int dbSearchStr(int did, char_t *tablename,
238        char_t *colName, char_t *value, int flags)
239{
240        int                     tid, nRows, nColumns, column;
241        dbTable_t       *pTable;
242
243        a_assert(tablename);
244        a_assert(colName);
245        a_assert(value);
246
247        tid = dbGetTableId(0, tablename);
248        a_assert(tid >= 0);
249
250        if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) {
251                pTable = dbListTables[tid];
252        } else {
253                return DB_ERR_TABLE_NOT_FOUND;
254        }
255       
256        nColumns = pTable->nColumns;
257        nRows = pTable->nRows;
258        column = GetColumnIndex(tid, colName);
259        a_assert (column >= 0);
260
261        if (column >= 0) {
262                char_t  *compareVal;
263                int             row, *pRow;
264/*
265 *              Scan through rows until we find a match.
266 *              Note that some of these rows may be deleted!
267 */
268                row = 0;
269                while (row < nRows) {
270                        pRow = pTable->rows[row];
271                        if (pRow) {
272                                compareVal = (char_t *)(pRow[column]);
273                                if (compareVal && (gstrcmp(compareVal, value) == 0)) {
274                                        return row;
275                                }
276                        }
277                        row++;
278                }
279        } else {
280/*
281 *              Return -2 if search column was not found
282 */
283                trace(3, T("DB: Unable to find column <%s> in table <%s>\n"),
284                        colName, tablename);
285                return DB_ERR_COL_NOT_FOUND;
286        }
287
288        return -1;
289}
290
291/******************************************************************************/
292/*
293 *      Add a new row to the given table.  Return the new row ID.
294 */
295
296int dbAddRow(int did, char_t *tablename)
297{
298        int                     tid, size;
299        dbTable_t       *pTable;
300
301        a_assert(tablename);
302
303        tid = dbGetTableId(0, tablename);
304        a_assert(tid >= 0);
305
306        if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) {
307                pTable = dbListTables[tid];
308        } else {
309                return DB_ERR_TABLE_NOT_FOUND;
310        }
311
312        a_assert(pTable);
313
314        if (pTable) {
315                trace(5, T("DB: Adding a row to table <%s>\n"), tablename);
316
317                size = pTable->nColumns * max(sizeof(int), sizeof(char_t *));
318                return hAllocEntry((void***) &(pTable->rows), &(pTable->nRows), size);
319        }
320
321        return -1;
322}
323
324/******************************************************************************/
325/*
326 *      Delete a row in the table. 
327 */
328
329int dbDeleteRow(int did, char_t *tablename, int row)
330{
331        int                     tid, nColumns, nRows;
332        dbTable_t       *pTable;
333
334        a_assert(tablename);
335        tid = dbGetTableId(0, tablename);
336        a_assert(tid >= 0);
337
338        if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) {
339                pTable = dbListTables[tid];
340        } else {
341                return DB_ERR_TABLE_NOT_FOUND;
342        }
343
344        nColumns = pTable->nColumns;
345        nRows = pTable->nRows;
346
347        if ((row >= 0) && (row < nRows)) {
348                int *pRow = pTable->rows[row];
349
350                if (pRow) {
351                        int     column = 0;
352/*
353 *                      Free up any allocated strings
354 */
355                        while (column < nColumns) {
356                                if (pRow[column] &&
357                                        (pTable->columnTypes[column] == T_STRING)) {
358                                        bfree(B_L, (char_t *)pRow[column]);
359                                }
360
361                                column++;
362                        }
363/*
364 *                      Zero out the row for safety
365 */
366                        memset(pRow, 0, nColumns * max(sizeof(int), sizeof(char_t *)));
367
368                        bfreeSafe(B_L, pRow);
369                        pTable->nRows = hFree((void ***)&pTable->rows, row);
370                        trace(5, T("DB: Deleted row <%d> from table <%s>\n"),
371                                row, tablename);
372                }
373                return 0;
374        } else {
375                trace(3, T("DB: Unable to delete row <%d> from table <%s>\n"),
376                        row, tablename);
377        }
378       
379        return -1;
380}
381
382/*****************************************************************************/
383/*
384 *      Grow the rows in the table to the nominated size.
385 */
386
387int dbSetTableNrow(int did, char_t *tablename, int nNewRows)
388{
389        int                     nRet, tid, nRows, nColumns;
390        dbTable_t       *pTable;
391
392        a_assert(tablename);
393        tid = dbGetTableId(0, tablename);
394        a_assert(tid >= 0) ;
395
396        if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) {
397                pTable = dbListTables[tid];
398        } else {
399                return DB_ERR_TABLE_NOT_FOUND;
400        }
401
402        nRet = -1;
403
404        a_assert(pTable);
405        if (pTable) {
406                nColumns = pTable->nColumns;
407                nRows = pTable->nRows;
408                nRet = 0;
409
410                if (nRows >= nNewRows) {
411/*             
412 *              If number of rows already allocated exceeds requested number, do nothing
413 */
414                        trace(4, T("DB: Ignoring row set to <%d> in table <%s>\n"),
415                                nNewRows, tablename);
416                } else {
417                        trace(4, T("DB: Setting rows to <%d> in table <%s>\n"),
418                                nNewRows, tablename);
419                        while (pTable->nRows < nNewRows) {
420                                if (dbAddRow(did, tablename) < 0) {
421                                        return -1;
422                                }
423                        }
424                }
425        }
426
427        return nRet;
428}
429
430/******************************************************************************/
431/*
432 *      Return the number of rows in the given table
433 */
434
435int dbGetTableNrow(int did, char_t *tablename)
436{
437        int tid;
438       
439        a_assert(tablename);
440        tid = dbGetTableId(did, tablename);
441
442        if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) {
443                return (dbListTables[tid])->nRows;
444        } else {
445                return -1;
446        }
447}
448
449/******************************************************************************/
450/*
451 *      Do table driven read of the database
452 */
453
454int dbReadInt(int did, char_t *table, char_t *column, int row, int *returnValue)
455{
456        int                     colIndex, *pRow, tid;
457        dbTable_t       *pTable;
458       
459        a_assert(table);
460        a_assert(column);
461        a_assert(returnValue);
462
463        tid = dbGetTableId(0, table);
464        a_assert(tid >= 0);
465
466/*
467 *      Return -6 if table is not found
468 */
469        if (tid < 0) {
470                return DB_ERR_TABLE_NOT_FOUND;
471        }
472
473/*
474 *      Return -7 if table id has been deleted
475 */
476        pTable = dbListTables[tid];
477        if (pTable == NULL) {
478                return DB_ERR_TABLE_DELETED;
479        }
480
481        a_assert(row >= 0);
482
483        if ((row >= 0) && (row < pTable->nRows)) {
484                colIndex = GetColumnIndex(tid, column);
485                a_assert(colIndex >= 0);
486
487                if (colIndex >= 0) {
488                        pRow = pTable->rows[row];
489                        if (pRow) {
490                                *returnValue = pRow[colIndex];
491                                return 0;
492                        } 
493                        return DB_ERR_ROW_DELETED;
494                }
495                return DB_ERR_COL_NOT_FOUND;
496        }
497
498        return DB_ERR_ROW_NOT_FOUND;
499}
500
501/******************************************************************************/
502/*
503 *      dbReadStr calls dbReadInt to do table driven read of database
504 */
505
506int dbReadStr(int did, char_t *table, char_t *column, int row,
507                char_t **returnValue)
508{
509        return dbReadInt(did, table, column, row, (int *)returnValue);
510}
511
512/******************************************************************************/
513/*
514 *      The dbWriteInt function writes a value into a table at a given row and
515 *      column.  The existence of the row and column is verified before the
516 *      write.  0 is returned on succes, -1 is returned on error.
517 */
518
519int dbWriteInt(int did, char_t *table, char_t *column, int row, int iData)
520{
521        int                     tid, colIndex, *pRow;
522        dbTable_t       *pTable;
523
524        a_assert(table);
525        a_assert(column);
526
527/*
528 *      Make sure that this table exists
529 */
530        tid = dbGetTableId(0, table);
531        a_assert(tid >= 0);
532
533        if (tid < 0) {
534                return DB_ERR_TABLE_NOT_FOUND;
535        }
536
537        pTable = dbListTables[tid];
538       
539        if (pTable) {
540/*
541 *              Make sure that the column exists
542 */
543                colIndex = GetColumnIndex(tid, column);
544                a_assert(colIndex >= 0);
545                if (colIndex >= 0) {
546/*
547 *                      Make sure that the row exists
548 */
549                        a_assert((row >= 0) && (row < pTable->nRows));
550                        if ((row >= 0) && (row < pTable->nRows)) {
551                                pRow = pTable->rows[row];
552                                if (pRow) {
553                                        pRow[colIndex] = iData;
554                                        return 0;
555                                }
556                                return DB_ERR_ROW_DELETED;
557                        }
558                        return DB_ERR_ROW_NOT_FOUND;
559                }
560                return DB_ERR_COL_NOT_FOUND;
561        }
562
563        return DB_ERR_TABLE_DELETED;
564}
565
566/******************************************************************************/
567/*
568 *      The dbWriteStr function writes a string value into a table at a given row
569 *      and column.  The existence of the row and column is verified before the
570 *      write.  The column is also checked to confirm it is a string field.
571 *      0 is returned on succes, -1 is returned on error.
572 */
573
574int dbWriteStr(int did, char_t *table, char_t *column, int row, char_t *s)
575{
576        int                     tid, colIndex;
577        int                     *pRow;
578        char_t          *ptr;
579        dbTable_t       *pTable;
580
581        a_assert(table);
582        a_assert(column);
583
584        tid = dbGetTableId(0, table);
585        a_assert(tid >= 0);
586
587        if (tid < 0) {
588                return DB_ERR_TABLE_NOT_FOUND;
589        }
590
591/*
592 *      Make sure that this table exists
593 */
594        pTable = dbListTables[tid];
595        a_assert(pTable);
596        if (!pTable) {
597                return DB_ERR_TABLE_DELETED;
598        }
599
600/*
601 *      Make sure that this column exists
602 */
603        colIndex = GetColumnIndex(tid, column);
604        if (colIndex < 0) {
605                return DB_ERR_COL_NOT_FOUND;
606        }
607
608/*
609 *      Make sure that this column is a string column
610 */
611        if (pTable->columnTypes[colIndex] != T_STRING) {
612                return DB_ERR_BAD_FORMAT;
613        }
614
615/*
616 *      Make sure that the row exists
617 */
618        a_assert((row >= 0) && (row < pTable->nRows));
619        if ((row >= 0) && (row < pTable->nRows)) {
620                pRow = pTable->rows[row];
621        } else {
622                return DB_ERR_ROW_NOT_FOUND;
623        }
624
625        if (!pRow) {
626                return DB_ERR_ROW_DELETED;
627        }
628
629/*
630 *      If the column already has a value, be sure to delete it to prevent
631 *      memory leaks.
632 */
633        if (pRow[colIndex]) {
634                bfree(B_L, (char_t *) pRow[colIndex]);
635        }
636
637/*
638 *      Make sure we make a copy of the string to write into the column.
639 *      This allocated string will be deleted when the row is deleted.
640 */
641        ptr = bstrdup(B_L, s);
642        pRow[colIndex] = (int)ptr;
643
644        return 0;
645}
646
647/******************************************************************************/
648/*
649 *      Print a key-value pair to a file
650 */
651
652static int dbWriteKeyValue(int fd, char_t *key, char_t *value)
653{
654        int             rc;
655        int             len;
656        char_t  *pLineOut;
657
658        a_assert(key && *key);
659        a_assert(value);
660       
661        fmtAlloc(&pLineOut, BUF_MAX, T("%s=%s\n"), key, value);
662
663        if (pLineOut) {
664                len = gstrlen(pLineOut);
665#if CE
666                rc = writeUniToAsc(fd, pLineOut, len);
667#else
668                rc = gwrite(fd, pLineOut, len);
669#endif
670                bfree(B_L, pLineOut);
671        } else {
672                rc = -1;
673        }
674
675        return rc;
676}
677
678/******************************************************************************/
679/*
680 *      Persist a database to a file
681 */
682
683int dbSave(int did, char_t *filename, int flags)
684{
685        int                     row, column, nColumns, nRows, fd, rc;
686        int                     *colTypes, *pRow, nRet, tid;
687        char_t          *path, *tmpFile, *tmpNum;
688        char_t          **colNames;
689        dbTable_t       *pTable;
690
691        trace(5, T("DB: About to save database to file\n"));
692
693        a_assert(dbMaxTables > 0);
694
695/*
696 *      First write to a temporary file, then switch around later.
697 */
698        fmtAlloc(&tmpFile, FNAMESIZE, T("%s/data.tmp"), basicGetProductDir());
699        if ((fd = gopen(tmpFile,
700                O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0666)) < 0) {
701                trace(1, T("WARNING: Failed to open file %s\n"), tmpFile);
702                bfree(B_L, tmpFile);
703                return -1;
704        }
705
706        nRet = 0;
707
708        for (tid = 0; (tid < dbMaxTables) && (nRet != -1); tid++) {
709                pTable = dbListTables[tid];
710
711                if (pTable) {
712/*
713 *                      Print the TABLE=tableName directive to the file
714 */
715                        rc = dbWriteKeyValue(fd, KEYWORD_TABLE, pTable->name);
716
717                        nColumns = pTable->nColumns;
718                        nRows = pTable->nRows;
719
720                        for (row = 0; (row < nRows) && (nRet == 0); row++) {
721                                pRow = pTable->rows[row];
722/*
723 *                              if row is NULL, the row has been deleted, so don't
724 *                              write it out.
725 */
726                                if ((pRow == NULL) || (pRow[0] == '\0') ||
727                                        (*(char_t *)(pRow[0]) == '\0')) {
728                                        continue;
729                                }
730/*
731 *                              Print the ROW=rowNumber directive to the file
732 */
733                                fmtAlloc(&tmpNum, 20, T("%d"), row);           
734                                rc = dbWriteKeyValue(fd, KEYWORD_ROW, tmpNum);
735                                bfreeSafe(B_L, tmpNum);
736
737                                colNames = pTable->columnNames;
738                                colTypes = pTable->columnTypes;
739/*
740 *                              Print the key-value pairs (COLUMN=value) for data cells
741 */
742                                for (column = 0; (column < nColumns) && (rc >= 0);
743                                        column++, colNames++, colTypes++) {
744                                        if (*colTypes == T_STRING) {
745                                                rc = dbWriteKeyValue(fd, *colNames,
746                                                        (char_t *)(pRow[column]));
747                                        } else {
748                                                fmtAlloc(&tmpNum, 20, T("%d"), pRow[column]);           
749                                                rc = dbWriteKeyValue(fd, *colNames, tmpNum);
750                                                bfreeSafe(B_L, tmpNum);
751                                        }
752                                }
753
754                                if (rc < 0) {
755                                        trace(1, T("WARNING: Failed to write to file %s\n"),
756                                                tmpFile);
757                                        nRet = -1;
758                                }
759                        }
760                }
761        }
762
763        gclose(fd);
764
765/*
766 *      Replace the existing file with the temporary file, if no errors
767 */
768        if (nRet == 0) {
769                fmtAlloc(&path, FNAMESIZE, T("%s/%s"), basicGetProductDir(), filename);
770
771                gunlink(path);
772                if (grename(tmpFile, path) != 0) {
773                        trace(1, T("WARNING: Failed to rename %s to %s\n"), tmpFile, path);
774                        nRet = -1;
775                }
776
777                bfree(B_L, path);
778        }
779
780        bfree(B_L, tmpFile);
781
782        return nRet;
783}
784
785/******************************************************************************/
786/*
787 *      Crack a keyword=value string into keyword and value. We can change buf.
788 */
789
790static int crack(char_t *buf, char_t **key, char_t **val)
791{
792        char_t  *ptr;
793
794        if ((ptr = gstrrchr(buf, '\n')) != NULL ||
795                        (ptr = gstrrchr(buf, '\r')) != NULL) {
796                *ptr = '\0';
797        }
798
799/*
800 *      Find the = sign. It must exist.
801 */
802        if ((ptr = gstrstr(buf, T("="))) == NULL) {
803                return -1;
804        }
805
806        *ptr++ = '\0';
807        *key = trim(buf);
808        *val = trim(ptr);
809
810        return 0;
811}
812
813/******************************************************************************/
814/*
815 *      Parse the file. These files consist of key-value pairs, separated by the
816 *  "=" sign. Parsing of tables starts with the "TABLE=value" pair, and rows
817 *      are parsed starting with the "ROW=value" pair.
818 */
819
820int dbLoad(int did, char_t *filename, int flags)
821{
822        gstat_t         sbuf;
823        char_t          *buf, *keyword, *value, *path, *ptr;
824        char_t          *tablename;
825        int                     fd, tid, row;
826        dbTable_t       *pTable;
827
828    a_assert(did >= 0);
829
830        fmtAlloc(&path, FNAMESIZE, T("%s/%s"), basicGetProductDir(), filename);
831        trace(4, T("DB: About to read data file <%s>\n"), path);
832
833        if (gstat(path, &sbuf) < 0) {
834                trace(3, T("DB: Failed to stat persistent data file.\n"));
835                bfree(B_L, path);
836                return -1;
837        }
838
839        fd = gopen(path, O_RDONLY | O_BINARY, 0666);
840        bfree(B_L, path);
841
842        if (fd < 0) {
843                trace(3, T("DB: No persistent data file present.\n"));
844                return -1;
845        }
846
847        if (sbuf.st_size <= 0) {
848                trace(3, T("DB: Persistent data file is empty.\n"));
849                gclose(fd);
850                return -1;
851        }
852/*
853 *      Read entire file into temporary buffer
854 */
855        buf = balloc(B_L, sbuf.st_size + 1);
856#if CE
857        if (readAscToUni(fd, &buf, sbuf.st_size) != (int)sbuf.st_size) {
858#else
859        if (gread(fd, buf, sbuf.st_size) != (int)sbuf.st_size) {
860#endif
861                trace(3, T("DB: Persistent data read failed.\n"));
862                bfree(B_L, buf);
863                gclose(fd);
864                return -1;
865        }
866
867        gclose(fd);
868        *(buf + sbuf.st_size) = '\0';
869
870        row = -1;
871        tid = -1;
872        pTable = NULL;
873        ptr = gstrtok(buf, T("\n"));
874        tablename = NULL;
875
876        do {
877                if (crack(ptr, &keyword, &value) < 0) {
878                        trace(5, T("DB: Failed to crack line %s\n"), ptr);
879                        continue;
880                }
881
882                a_assert(keyword && *keyword);
883
884                if (gstrcmp(keyword, KEYWORD_TABLE) == 0) {
885/*
886 *                      Table name found, check to see if it's registered
887 */
888                        if (tablename) {
889                                bfree(B_L, tablename);
890                        }
891
892                        tablename = bstrdup(B_L, value);
893                        tid = dbGetTableId(did, tablename);
894
895                        if (tid >= 0) {
896                                pTable = dbListTables[tid];
897                        } else {
898                                pTable = NULL;
899                        }
900
901                } else if (gstrcmp(keyword, KEYWORD_ROW) == 0) {
902/*
903 *                      Row/Record indicator found, add a new row to table
904 */
905                        if (tid >= 0) {
906                                int nRows = dbGetTableNrow(did, tablename);
907
908                                if (dbSetTableNrow(did, tablename, nRows + 1) == 0) {
909                                        row = nRows;
910                                }
911                        }
912
913                } else if (row != -1) {
914/*
915 *                      some other data found, assume it's a COLUMN=value
916 */
917                        int nColumn = GetColumnIndex(tid, keyword);
918
919                        if ((nColumn >= 0) && (pTable != NULL)) {
920                                int nColumnType = pTable->columnTypes[nColumn];
921                                if (nColumnType == T_STRING) {
922                                        dbWriteStr(did, tablename, keyword, row, value);
923                                } else {
924                                        dbWriteInt(did, tablename, keyword, row, gstrtoi(value));
925                                }
926                        }
927                }
928        } while ((ptr = gstrtok(NULL, T("\n"))) != NULL);
929
930        if (tablename) {
931                bfree(B_L, tablename);
932        }
933
934        bfree(B_L, buf);
935
936        return 0;
937}
938
939/******************************************************************************/
940/*
941 *      Return a table id given the table name
942 */
943
944int dbGetTableId(int did, char_t *tablename)
945{
946        int                     tid;
947        dbTable_t       *pTable;
948
949        a_assert(tablename);
950
951        for (tid = 0; (tid < dbMaxTables); tid++) {
952                if ((pTable = dbListTables[tid]) != NULL) {
953                        if (gstrcmp(tablename, pTable->name) == 0) {
954                                return tid;
955                        }
956                }
957        }
958       
959        return -1;
960}
961
962/******************************************************************************/
963/*     
964 *      Return a pointer to the table name, given its ID
965 */
966
967char_t *dbGetTableName(int did, int tid)
968{
969        if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) {
970                return (dbListTables[tid])->name;
971        }
972
973        return NULL;
974}
975
976/******************************************************************************/
977/*
978 *      Trim leading white space.
979 */
980
981static char_t *trim(char_t *str)
982{
983        while (isspace((int)*str)) {
984                str++;
985        }
986        return str;
987}
988
989/******************************************************************************/
990/*
991 *      Return a column index given the column name
992 */
993
994static int GetColumnIndex(int tid, char_t *colName)
995{
996        int                     column;
997        dbTable_t       *pTable;
998
999        a_assert(colName);
1000
1001        if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) {
1002                pTable = dbListTables[tid];
1003
1004                for (column = 0; (column < pTable->nColumns); column++) {
1005                        if (gstrcmp(colName, pTable->columnNames[column]) == 0)
1006                                return column;
1007                }
1008        }
1009
1010        return -1;
1011}
1012
1013/******************************************************************************/
1014/*
1015 *      Set the prefix-directory
1016 */
1017
1018void basicSetProductDir(char_t *proddir)
1019{
1020        int len;
1021
1022        if (basicProdDir != NULL); {
1023                bfree(B_L, basicProdDir);
1024        }
1025   
1026        basicProdDir = bstrdup(B_L, proddir);
1027/*
1028 *      Make sure that prefix-directory doesn't end with a '/'
1029 */
1030        len = gstrlen(basicProdDir);
1031        if ((len > 0) && *(basicProdDir + len - 1) == '/') {
1032                *(basicProdDir+len-1) = '\0';
1033        }
1034}
1035
1036/******************************************************************************/
1037/*
1038 *      Return the prefix-directory
1039 */
1040
1041char_t *basicGetProductDir()
1042{
1043        if (basicProdDir) {
1044                return basicProdDir;
1045        } else {
1046                return basicDefaultDir;
1047        }
1048}
1049
1050/******************************************************************************/
Note: See TracBrowser for help on using the repository browser.