00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00024 
00025 
00026 
00027 #include <stdlib.h>
00028 #include <malloc.h>
00029 #include <stdio.h>
00030 #include <string.h>
00031 #include "lcas_log.h"
00032 #include "_lcas_db_read.h"
00033 
00034 
00035 
00036 
00037 #define MAXDBENTRIES 250 
00038 #define MAXPAIRS     2   
00041 #define WHITESPACE_CHARS " \t\n" 
00042 #define QUOTING_CHARS    "\"" 
00043 #define ESCAPING_CHARS   "\\" 
00044 #define COMMENT_CHARS    "#" 
00047 #define PAIR_SEP_CHARS ","
00048 
00049 #define VARVAL_SEP_CHARS "="
00050 
00051 
00052 
00053 
00054 
00059 #define PAIR_TERMINATOR_CHARS PAIR_SEP_CHARS WHITESPACE_CHARS
00060 
00064 #define VARVAL_TERMINATOR_CHARS VARVAL_SEP_CHARS WHITESPACE_CHARS
00065 
00066 #ifndef NUL
00067 #define NUL '\0' 
00068 #endif
00069 
00070 
00071 
00072 
00073 static int lcas_db_read_entries(FILE *);
00074 static int lcas_db_parse_line(char *, lcas_db_entry_t **);
00075 static int lcas_db_parse_pair(char *, char **, char **);
00076 static int lcas_db_parse_string(char **);
00077 
00078 
00079 
00080 
00081 static lcas_db_entry_t *  lcas_db_list=NULL; 
00083 
00084 
00085 
00086 
00087 lcas_db_entry_t ** lcas_db_read(
00088         char * lcas_db_fname
00089 )
00090 {
00091     FILE * lcas_db_fhandle;
00092     int    no_entries;
00093 
00094     lcas_db_fhandle = fopen(lcas_db_fname, "r");
00095     if (lcas_db_fhandle == NULL)
00096     {
00097         
00098         return NULL;
00099     }
00100 
00101     no_entries=lcas_db_read_entries(lcas_db_fhandle);
00102     if (no_entries < 0)
00103     {
00104         lcas_log(0,"lcas.mod-lcas_db_read(): Parse error in line %d of %s\n",
00105             -(no_entries), lcas_db_fname);
00106         fclose(lcas_db_fhandle);
00107         return NULL;
00108     }
00109     else if (no_entries > MAXDBENTRIES)
00110     {
00111         lcas_log(0,"lcas.mod-lcas_db_read(): Too many entries found in %s\n",
00112             lcas_db_fname);
00113         lcas_log(0,"lcas.mod-lcas_db_read(): Only the first %d entries are used\n",
00114             MAXDBENTRIES);
00115     }
00116     fclose(lcas_db_fhandle);
00117 
00118     return &lcas_db_list;
00119 }
00120 
00130 static int lcas_db_read_entries(
00131         FILE * dbstream
00132 )
00133 {
00134     char               line[1024];
00135     int                nlines=0;
00136     int                no_entries=0;
00137     lcas_db_entry_t *  entry=NULL;
00138 
00139     nlines=0;
00140     no_entries=0;
00141 
00142     while (fgets(line, sizeof(line), dbstream))
00143     {
00144         ++nlines;
00145 
00146         if (! lcas_db_parse_line(line, &entry))
00147         {
00148             
00149             if (entry != NULL) free(entry);
00150             return -(nlines);
00151         }
00152         if (entry != NULL)
00153         {
00154             lcas_log_debug(3,"line %d: %s, %s\n",nlines,entry->pluginname,entry->pluginargs);
00155             
00156             ++no_entries;
00157             if (no_entries > MAXDBENTRIES)
00158             {
00159                 if (entry != NULL) free(entry);
00160                 return no_entries;
00161             }
00162             if ( lcas_db_fill_entry(&lcas_db_list, entry)==NULL )
00163             {
00164                 
00165                 if (entry != NULL) free(entry);
00166                 return -(nlines);
00167             }
00168             if (entry != NULL) free(entry);
00169             entry=NULL;
00170         }
00171         else
00172         {
00173             
00174             continue;
00175         }
00176     }
00177     if (entry != NULL) free(entry);
00178     return no_entries;
00179 }
00180 
00181 
00182 
00183 
00184 
00185 lcas_db_entry_t * lcas_db_fill_entry(
00186         lcas_db_entry_t ** list,
00187         lcas_db_entry_t * entry
00188 )
00189 {
00190     lcas_db_entry_t * plist;
00191 
00192     if (entry == NULL)
00193     {
00194         lcas_log(0,"lcas.mod-lcas_db_fill_entry(): error null entry\n");
00195         return NULL;
00196     }
00197 
00198     if (!(*list))
00199     {
00200         lcas_log_debug(2,"lcas.mod-lcas_db_fill_entry(): creating first list entry\n");
00201         *list=plist=(lcas_db_entry_t *)malloc(sizeof(lcas_db_entry_t));
00202     }
00203     else
00204     {
00205         lcas_log_debug(2,"lcas.mod-lcas_db_fill_entry(): creating new list entry\n");
00206         plist=*list;
00207         while (plist->next) plist=plist->next;
00208         plist=plist->next=(lcas_db_entry_t *)malloc(sizeof(lcas_db_entry_t));
00209     }
00210     if (!plist)
00211     {
00212         lcas_log(0,"lcas.mod-lcas_db_fill_entry(): error creating new list entry\n");
00213         return NULL;
00214     }
00215     plist->next=NULL;
00216 
00217     if (entry->pluginname != NULL)
00218     {
00219         strncpy(plist->pluginname,entry->pluginname,LCAS_MAXPATHLEN);
00220         (plist->pluginname)[LCAS_MAXPATHLEN]=NUL;
00221     }
00222     else
00223         strncpy(plist->pluginname,"",LCAS_MAXPATHLEN);
00224 
00225     if (entry->pluginargs != NULL)
00226     {
00227         strncpy(plist->pluginargs,entry->pluginargs,LCAS_MAXARGSTRING);
00228         (plist->pluginargs)[LCAS_MAXARGSTRING]=NUL;
00229     }
00230     else
00231         strncpy(plist->pluginargs,"",LCAS_MAXARGSTRING);
00232 
00233     return plist;
00234 }
00235 
00248 static int lcas_db_parse_line(
00249         char * line,
00250         lcas_db_entry_t ** entry
00251 )
00252 {
00253     char *            var_val_pairs[MAXPAIRS];
00254     char *            var;
00255     char *            val;
00256     int               ipair;
00257     int               no_pairs;
00258     size_t            len;
00259     lcas_db_entry_t * tmp_entry=NULL;
00260 
00261     
00262     if ((line == NULL) || (*entry != NULL))
00263     {
00264         lcas_log(0,"lcas.mod-lcas_db_parse_line(): something wrong with arguments\n");
00265         goto error;
00266     }
00267 
00268     
00269     line += strspn(line, WHITESPACE_CHARS);
00270 
00271     
00272     if (strchr(COMMENT_CHARS, *line) != NULL) 
00273     {
00274         
00275         *entry=NULL;
00276         return 1;
00277     }
00278 
00279     
00280     if (*line == NUL)
00281     {
00282         
00283         *entry=NULL;
00284         return 1;
00285     }
00286 
00287     
00288     ipair=0;
00289     len=0;
00290     while (*line != NUL)
00291     {
00292         len=strcspn(line, PAIR_SEP_CHARS);
00293         if (len > 0)
00294         {
00295             var_val_pairs[ipair] = line;
00296             ipair++;
00297             line+=len;
00298             if (*line == NUL)
00299             {
00300                 
00301                 continue;
00302             }
00303             if (strchr(PAIR_SEP_CHARS, *line) != NULL)
00304             {
00305                 *line=NUL;
00306                 line += 1;
00307             }
00308         }
00309         else
00310         {
00311             
00312             line += 1;
00313         }
00314         line += strspn(line, WHITESPACE_CHARS);
00315     }
00316     no_pairs=ipair;
00317     if (no_pairs)
00318     {
00319         tmp_entry=malloc(sizeof(*tmp_entry));
00320         if (tmp_entry == NULL)
00321         {
00322             lcas_log(0,"lcas.mod-lcas_db_parse_line(): error allocating memory\n");
00323             goto error;
00324         }
00325 
00326         for (ipair=0; ipair < no_pairs; ipair++)
00327         {
00328             int rc=0;
00329             lcas_log_debug(3,"pair %d:%s-endpair\n",ipair, var_val_pairs[ipair]);
00330             rc=lcas_db_parse_pair(var_val_pairs[ipair], &var, &val);
00331             if (! rc)
00332             {
00333                 
00334                 lcas_log(0,"lcas.mod-lcas_db_parse_line(): error parsing variable-value pair\n");
00335                 goto error;
00336             }
00337             lcas_log_debug(3,"var: %s, value: %s\n",var,val);
00338 
00339             if (strncmp(var,"pluginname",strlen("pluginname")) == 0)
00340             {
00341                 
00342                 strncpy(tmp_entry->pluginname,val,LCAS_MAXPATHLEN);
00343                 (tmp_entry->pluginname)[LCAS_MAXPATHLEN]=NUL;
00344             }
00345             else if (strncmp(var,"pluginargs",strlen("pluginargs")) == 0)
00346             {
00347                 
00348                 strncpy(tmp_entry->pluginargs,val,LCAS_MAXARGSTRING);
00349                 (tmp_entry->pluginargs)[LCAS_MAXARGSTRING]=NUL;
00350             }
00351             else
00352             {
00353                 
00354             }
00355         }
00356     }
00357 
00358     
00359     *entry=tmp_entry;
00360     return 1;
00361 
00362   error:
00363     if (tmp_entry != NULL) free(tmp_entry);
00364     return 0;
00365 }
00366 
00381 static int lcas_db_parse_pair(
00382         char * pair,
00383         char ** pvar,
00384         char ** pval
00385 )
00386 {
00387     int    len;
00388     char * var;
00389     char * val;
00390 
00391     if (pair == NULL)
00392     {
00393         lcas_log(0,"lcas.mod-lcas_db_parse_pair(): cannot parse empty pair\n");
00394         return 0;
00395     }
00396 
00397     
00398     pair += strspn(pair, WHITESPACE_CHARS);
00399     if (*pair == NUL)
00400     {
00401         lcas_log(0,"lcas.mod-lcas_db_parse_pair(): cannot parse empty pair\n");
00402         return 0;
00403     }
00404 
00405     var=pair;
00406     len=strcspn(pair, VARVAL_SEP_CHARS);
00407     pair+=len;
00408     if (*pair == NUL)
00409     {
00410         
00411         lcas_log(0,"lcas.mod-lcas_db_parse_pair(): cannot find =\n");
00412         return 0;
00413     }
00414 
00415     if (strchr(VARVAL_SEP_CHARS, *pair) != NULL)
00416     {
00417         
00418         *pair=NUL;
00419         if (! lcas_db_parse_string(&var))
00420         {
00421             
00422             return 0;
00423         }
00424         pair+=1;
00425         if (*pair==NUL)
00426         {
00427             
00428 
00429             val=pair;
00430             *pvar=var;
00431             *pval=val;
00432             return 1;
00433         }
00434         else
00435         {
00436             
00437             pair += strspn(pair, WHITESPACE_CHARS);
00438             if (*pair == NUL)
00439             {
00440                 
00441 
00442                 val=pair;
00443                 *pvar=var;
00444                 *pval=val;
00445                 return 1;
00446             }
00447             val=pair;
00448             if (! lcas_db_parse_string(&val))
00449             {
00450                 
00451                 return 0;
00452             }
00453         }
00454     }
00455     else
00456     {
00457         
00458         lcas_log(0,"lcas.mod-lcas_db_parse_pair(): cannot find =\n");
00459         return 0;
00460     }
00461 
00462     
00463     *pvar=var;
00464     *pval=val;
00465     return 1;
00466 }
00467 
00478 static int lcas_db_parse_string(
00479         char ** pstring
00480 )
00481 {
00482     char * end;
00483     char * string;
00484 
00485     string=*pstring;
00486 
00487     if (*string==NUL)
00488     {
00489         lcas_log(0,"lcas.mod-lcas_db_parse_string(): error parsing null string\n");
00490         return 0;
00491     }
00492 
00493     
00494     if (strchr(QUOTING_CHARS, *string) != NULL)
00495     {
00496         
00497 
00498 
00499 
00500         string++;
00501         end=string;
00502         do
00503         {
00504             end += strcspn(end, QUOTING_CHARS);
00505             if (*end == NUL)
00506             {
00507                 lcas_log(0,"lcas.mod-lcas_db_parse_string(): missing closing quote\n");
00508                 return 0; 
00509             }
00510 
00511             
00512         }
00513         while (strchr(ESCAPING_CHARS, *(end - 1)) != NULL);
00514     }
00515     else
00516     {
00517         end = string + strcspn(string, WHITESPACE_CHARS);
00518     }
00519     *end=NUL;
00520     *pstring=string;
00521 
00522     return 1;
00523 }
00524 
00525 
00526 
00527 
00528 
00529 int lcas_db_clean_list(
00530         lcas_db_entry_t ** list
00531 )
00532 {
00533     lcas_db_entry_t * entry;
00534 
00535     entry=*list;
00536     while (entry)
00537     {
00538         lcas_db_entry_t * next_entry;
00539         lcas_log_debug(2,"cleaning db entry for module %s\n",entry->pluginname);
00540         next_entry=entry->next;
00541         free(entry);
00542         entry=next_entry;
00543     }
00544     *list=entry=NULL;
00545     return 0;
00546 }
00547 
00548 
00549 
00550 
00551 
00552 int lcas_db_clean()
00553 {
00554     if(lcas_db_clean_list(&lcas_db_list) != 0)
00555     {
00556         lcas_log(0,"lcas.mod-lcas_db_clean() error: could not clean list\n");
00557         return 1;
00558     }
00559     return 0;
00560 }
00561 
00562 
00563 
00564 
00565 
00566 
00567 
00568