00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00017
00018
00019
00020 #include <stdlib.h>
00021 #include <malloc.h>
00022 #include <stdio.h>
00023 #include <string.h>
00024 #include "lcmaps_log.h"
00025 #include "_lcmaps_db_read.h"
00026
00027
00028
00029
00030 #define MAXDBENTRIES 250
00031 #define MAXPAIRS 2
00034 #define WHITESPACE_CHARS " \t\n"
00035 #define QUOTING_CHARS "\""
00036 #define ESCAPING_CHARS "\\"
00037 #define COMMENT_CHARS "#"
00040 #define PAIR_SEP_CHARS ","
00041
00042 #define VARVAL_SEP_CHARS "="
00043
00044
00045
00046
00047
00052 #define PAIR_TERMINATOR_CHARS PAIR_SEP_CHARS WHITESPACE_CHARS
00053
00057 #define VARVAL_TERMINATOR_CHARS VARVAL_SEP_CHARS WHITESPACE_CHARS
00058
00059 #ifndef NUL
00060 #define NUL '\0'
00061 #endif
00062
00063
00064
00065
00066 static int lcmaps_db_read_entries(FILE *);
00067 static int lcmaps_db_parse_line(char *, lcmaps_db_entry_t **);
00068 static int lcmaps_db_parse_pair(char *, char **, char **);
00069 static int lcmaps_db_parse_string(char **);
00070
00071
00072
00073
00074 static lcmaps_db_entry_t * lcmaps_db_list=NULL;
00076
00077
00078
00079
00089 lcmaps_db_entry_t ** lcmaps_db_read(
00090 char * lcmaps_db_fname
00091 )
00092 {
00093 FILE * lcmaps_db_fhandle;
00094 int no_entries;
00095
00096 lcmaps_db_fhandle = fopen(lcmaps_db_fname, "r");
00097 if (lcmaps_db_fhandle == NULL)
00098 {
00099
00100 return NULL;
00101 }
00102
00103 no_entries=lcmaps_db_read_entries(lcmaps_db_fhandle);
00104 if (no_entries < 0)
00105 {
00106 lcmaps_log(0,"lcmaps.mod-lcmaps_db_read(): Parse error in line %d of %s\n",
00107 -(no_entries), lcmaps_db_fname);
00108 fclose(lcmaps_db_fhandle);
00109 return NULL;
00110 }
00111 else if (no_entries > MAXDBENTRIES)
00112 {
00113 lcmaps_log(0,"lcmaps.mod-lcmaps_db_read(): Too many entries found in %s\n",
00114 lcmaps_db_fname);
00115 lcmaps_log(0,"lcmaps.mod-lcmaps_db_read(): Only the first %d entries are used\n",
00116 MAXDBENTRIES);
00117 }
00118 fclose(lcmaps_db_fhandle);
00119
00120 return &lcmaps_db_list;
00121 }
00122
00132 static int lcmaps_db_read_entries(
00133 FILE * dbstream
00134 )
00135 {
00136 char line[1024];
00137 int nlines=0;
00138 int no_entries=0;
00139 lcmaps_db_entry_t * entry=NULL;
00140
00141 nlines=0;
00142 no_entries=0;
00143
00144 while (fgets(line, sizeof(line), dbstream))
00145 {
00146 ++nlines;
00147
00148 if (! lcmaps_db_parse_line(line, &entry))
00149 {
00150
00151 if (entry != NULL) free(entry);
00152 return -(nlines);
00153 }
00154 if (entry != NULL)
00155 {
00156 lcmaps_log_debug(3,"line %d: %s, %s\n",nlines,entry->pluginname,entry->pluginargs);
00157
00158 ++no_entries;
00159 if (no_entries > MAXDBENTRIES)
00160 {
00161 if (entry != NULL) free(entry);
00162 return no_entries;
00163 }
00164 if ( lcmaps_db_fill_entry(&lcmaps_db_list, entry)==NULL )
00165 {
00166
00167 if (entry != NULL) free(entry);
00168 return -(nlines);
00169 }
00170 if (entry != NULL) free(entry);
00171 entry=NULL;
00172 }
00173 else
00174 {
00175
00176 continue;
00177 }
00178 }
00179 if (entry != NULL) free(entry);
00180 return no_entries;
00181 }
00182
00183
00184
00185
00186
00198 lcmaps_db_entry_t * lcmaps_db_fill_entry(
00199 lcmaps_db_entry_t ** list,
00200 lcmaps_db_entry_t * entry
00201 )
00202 {
00203 lcmaps_db_entry_t * plist;
00204
00205 if (entry == NULL)
00206 {
00207 lcmaps_log(0,"lcmaps.mod-lcmaps_db_fill_entry(): error null entry\n");
00208 return NULL;
00209 }
00210
00211 if (!(*list))
00212 {
00213 lcmaps_log_debug(2,"lcmaps.mod-lcmaps_db_fill_entry(): creating first list entry\n");
00214 *list=plist=(lcmaps_db_entry_t *)malloc(sizeof(lcmaps_db_entry_t));
00215 }
00216 else
00217 {
00218 lcmaps_log_debug(2,"lcmaps.mod-lcmaps_db_fill_entry(): creating new list entry\n");
00219 plist=*list;
00220 while (plist->next) plist=plist->next;
00221 plist=plist->next=(lcmaps_db_entry_t *)malloc(sizeof(lcmaps_db_entry_t));
00222 }
00223 if (!plist)
00224 {
00225 lcmaps_log(0,"lcmaps.mod-lcmaps_db_fill_entry(): error creating new list entry\n");
00226 return NULL;
00227 }
00228 plist->next=NULL;
00229
00230 if (entry->pluginname != NULL)
00231 {
00232 strncpy(plist->pluginname,entry->pluginname,LCMAPS_MAXPATHLEN);
00233 (plist->pluginname)[LCMAPS_MAXPATHLEN]=NUL;
00234 }
00235 else
00236 strncpy(plist->pluginname,"",LCMAPS_MAXPATHLEN);
00237
00238 if (entry->pluginargs != NULL)
00239 {
00240 strncpy(plist->pluginargs,entry->pluginargs,LCMAPS_MAXARGSTRING);
00241 (plist->pluginargs)[LCMAPS_MAXARGSTRING]=NUL;
00242 }
00243 else
00244 strncpy(plist->pluginargs,"",LCMAPS_MAXARGSTRING);
00245
00246 return plist;
00247 }
00248
00261 static int lcmaps_db_parse_line(
00262 char * line,
00263 lcmaps_db_entry_t ** entry
00264 )
00265 {
00266 char * var_val_pairs[MAXPAIRS];
00267 char * var;
00268 char * val;
00269 int ipair;
00270 int no_pairs;
00271 size_t len;
00272 lcmaps_db_entry_t * tmp_entry=NULL;
00273
00274
00275 if ((line == NULL) || (*entry != NULL))
00276 {
00277 lcmaps_log(0,"lcmaps.mod-lcmaps_db_parse_line(): something wrong with arguments\n");
00278 goto error;
00279 }
00280
00281
00282 line += strspn(line, WHITESPACE_CHARS);
00283
00284
00285 if (strchr(COMMENT_CHARS, *line) != NULL)
00286 {
00287
00288 *entry=NULL;
00289 return 1;
00290 }
00291
00292
00293 if (*line == NUL)
00294 {
00295
00296 *entry=NULL;
00297 return 1;
00298 }
00299
00300
00301 ipair=0;
00302 len=0;
00303 while (*line != NUL)
00304 {
00305 len=strcspn(line, PAIR_SEP_CHARS);
00306 if (len > 0)
00307 {
00308 var_val_pairs[ipair] = line;
00309 ipair++;
00310 line+=len;
00311 if (*line == NUL)
00312 {
00313
00314 continue;
00315 }
00316 if (strchr(PAIR_SEP_CHARS, *line) != NULL)
00317 {
00318 *line=NUL;
00319 line += 1;
00320 }
00321 }
00322 else
00323 {
00324
00325 line += 1;
00326 }
00327 line += strspn(line, WHITESPACE_CHARS);
00328 }
00329 no_pairs=ipair;
00330 if (no_pairs)
00331 {
00332 tmp_entry=malloc(sizeof(*tmp_entry));
00333 if (tmp_entry == NULL)
00334 {
00335 lcmaps_log(0,"lcmaps.mod-lcmaps_db_parse_line(): error allocating memory\n");
00336 goto error;
00337 }
00338
00339
00340 (tmp_entry->pluginname)[0] = NUL;
00341 (tmp_entry->pluginargs)[0] = NUL;
00342 for (ipair=0; ipair < no_pairs; ipair++)
00343 {
00344 int rc=0;
00345 lcmaps_log_debug(3,"pair %d:%s-endpair\n",ipair, var_val_pairs[ipair]);
00346 rc=lcmaps_db_parse_pair(var_val_pairs[ipair], &var, &val);
00347 if (! rc)
00348 {
00349
00350 lcmaps_log(0,"lcmaps.mod-lcmaps_db_parse_line(): error parsing variable-value pair\n");
00351 goto error;
00352 }
00353 lcmaps_log_debug(3,"var: %s, value: %s\n",var,val);
00354
00355 if (strncmp(var,"pluginname",strlen("pluginname")) == 0)
00356 {
00357
00358 strncpy(tmp_entry->pluginname,val,LCMAPS_MAXPATHLEN);
00359 (tmp_entry->pluginname)[LCMAPS_MAXPATHLEN]=NUL;
00360 }
00361 else if (strncmp(var,"pluginargs",strlen("pluginargs")) == 0)
00362 {
00363
00364 strncpy(tmp_entry->pluginargs,val,LCMAPS_MAXARGSTRING);
00365 (tmp_entry->pluginargs)[LCMAPS_MAXARGSTRING]=NUL;
00366 }
00367 else
00368 {
00369
00370 }
00371 }
00372 }
00373
00374
00375 *entry=tmp_entry;
00376 return 1;
00377
00378 error:
00379 if (tmp_entry != NULL) free(tmp_entry);
00380 return 0;
00381 }
00382
00397 static int lcmaps_db_parse_pair(
00398 char * pair,
00399 char ** pvar,
00400 char ** pval
00401 )
00402 {
00403 int len;
00404 char * var;
00405 char * val;
00406
00407 if (pair == NULL)
00408 {
00409 lcmaps_log(0,"lcmaps.mod-lcmaps_db_parse_pair(): cannot parse empty pair\n");
00410 return 0;
00411 }
00412
00413
00414 pair += strspn(pair, WHITESPACE_CHARS);
00415 if (*pair == NUL)
00416 {
00417 lcmaps_log(0,"lcmaps.mod-lcmaps_db_parse_pair(): cannot parse empty pair\n");
00418 return 0;
00419 }
00420
00421 var=pair;
00422 len=strcspn(pair, VARVAL_SEP_CHARS);
00423 pair+=len;
00424 if (*pair == NUL)
00425 {
00426
00427 lcmaps_log(0,"lcmaps.mod-lcmaps_db_parse_pair(): cannot find =\n");
00428 return 0;
00429 }
00430
00431 if (strchr(VARVAL_SEP_CHARS, *pair) != NULL)
00432 {
00433
00434 *pair=NUL;
00435 if (! lcmaps_db_parse_string(&var))
00436 {
00437
00438 return 0;
00439 }
00440 pair+=1;
00441 if (*pair==NUL)
00442 {
00443
00444
00445 val=pair;
00446 *pvar=var;
00447 *pval=val;
00448 return 1;
00449 }
00450 else
00451 {
00452
00453 pair += strspn(pair, WHITESPACE_CHARS);
00454 if (*pair == NUL)
00455 {
00456
00457
00458 val=pair;
00459 *pvar=var;
00460 *pval=val;
00461 return 1;
00462 }
00463 val=pair;
00464 if (! lcmaps_db_parse_string(&val))
00465 {
00466
00467 return 0;
00468 }
00469 }
00470 }
00471 else
00472 {
00473
00474 lcmaps_log(0,"lcmaps.mod-lcmaps_db_parse_pair(): cannot find =\n");
00475 return 0;
00476 }
00477
00478
00479 *pvar=var;
00480 *pval=val;
00481 return 1;
00482 }
00483
00494 static int lcmaps_db_parse_string(
00495 char ** pstring
00496 )
00497 {
00498 char * end;
00499 char * string;
00500
00501 string=*pstring;
00502
00503 if (*string==NUL)
00504 {
00505 lcmaps_log(0,"lcmaps.mod-lcmaps_db_parse_string(): error parsing null string\n");
00506 return 0;
00507 }
00508
00509
00510 if (strchr(QUOTING_CHARS, *string) != NULL)
00511 {
00512
00513
00514
00515
00516 string++;
00517 end=string;
00518 do
00519 {
00520 end += strcspn(end, QUOTING_CHARS);
00521 if (*end == NUL)
00522 {
00523 lcmaps_log(0,"lcmaps.mod-lcmaps_db_parse_string(): missing closing quote\n");
00524 return 0;
00525 }
00526
00527
00528 }
00529 while (strchr(ESCAPING_CHARS, *(end - 1)) != NULL);
00530 }
00531 else
00532 {
00533 end = string + strcspn(string, WHITESPACE_CHARS);
00534 }
00535 *end=NUL;
00536 *pstring=string;
00537
00538 return 1;
00539 }
00540
00541
00542
00543
00544
00555 int lcmaps_db_clean_list(
00556 lcmaps_db_entry_t ** list
00557 )
00558 {
00559 lcmaps_db_entry_t * entry;
00560
00561 entry=*list;
00562 while (entry)
00563 {
00564 lcmaps_db_entry_t * next_entry;
00565 lcmaps_log_debug(2,"cleaning db entry for module %s\n",entry->pluginname);
00566 next_entry=entry->next;
00567 free(entry);
00568 entry=next_entry;
00569 }
00570 *list=entry=NULL;
00571 return 0;
00572 }
00573
00574
00575
00576
00577
00585 int lcmaps_db_clean()
00586 {
00587 if(lcmaps_db_clean_list(&lcmaps_db_list) != 0)
00588 {
00589 lcmaps_log(0,"lcmaps.mod-lcmaps_db_clean() error: could not clean list\n");
00590 return 1;
00591 }
00592 return 0;
00593 }
00594
00595
00596
00597
00598
00599
00600
00601