Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

lcmaps_db_read.c

Go to the documentation of this file.
00001 /*                                                                                                            
00002  * Copyright (c) 2001 EU DataGrid.                                                                             
00003  * For license conditions see http://www.eu-datagrid.org/license.html                                          
00004  *
00005  * Copyright (c) 2001, 2002 by 
00006  *     Martijn Steenbakkers <martijn@nikhef.nl>,
00007  *     David Groep <davidg@nikhef.nl>,
00008  *     NIKHEF Amsterdam, the Netherlands
00009  */
00010 
00017 /*****************************************************************************
00018                             Include header files
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                                 Definitions
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  * Characters that terminate pairs, values and variables in the lcmaps database file. This
00046  * is a combination of whitespace and separators.
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                           Module specific prototypes
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                        Define module specific variables
00073 ******************************************************************************/
00074 static lcmaps_db_entry_t *  lcmaps_db_list=NULL; 
00076 /******************************************************************************
00077     Function: lcmaps_db_read
00078     documentation in _lcmaps_db_read.h
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         /* Cannot open file */
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 /*    lcmaps_db_fill_entry(no_entries,NULL); */
00144     while (fgets(line, sizeof(line), dbstream))
00145     {
00146         ++nlines;
00147 
00148         if (! lcmaps_db_parse_line(line, &entry))
00149         {
00150             /* parse error, return line number */
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             /* entry found */
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                 /* error filling lcmaps_db */
00167                 if (entry != NULL) free(entry);
00168                 return -(nlines);
00169             }
00170             if (entry != NULL) free(entry);
00171             entry=NULL;
00172         }
00173         else
00174         {
00175             /* no entry found, but no error */
00176             continue;
00177         }
00178     }
00179     if (entry != NULL) free(entry);
00180     return no_entries;
00181 }
00182 
00183 /******************************************************************************
00184     Function: lcmaps_db_fill_entry
00185     documentation in _lcmaps_db_read.h
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     /* Check arguments */
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     /* Skip over leading whitespace */
00282     line += strspn(line, WHITESPACE_CHARS);
00283 
00284     /* Check for comment at start of line and ignore line if present */
00285     if (strchr(COMMENT_CHARS, *line) != NULL) 
00286     {
00287         /* Ignore line, return NULL entry. */
00288         *entry=NULL;
00289         return 1;
00290     }
00291 
00292     /* Check for empty line */
00293     if (*line == NUL)
00294     {
00295         /* Empty line, return NULL entry. */
00296         *entry=NULL;
00297         return 1;
00298     }
00299 
00300     /* Look for variable-value pairs by checking the PAIR_SEP_CHARS */
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                 /* probably end of line */
00314                 continue;
00315             }
00316             if (strchr(PAIR_SEP_CHARS, *line) != NULL)
00317             {
00318                 *line=NUL;
00319                 line += 1;
00320             }
00321         }
00322         else
00323         {
00324             /* len = 0, so *line=PAIR_SEP_CHARS */
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         /* Initialize tmp_entry */
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                 /* error parsing variable-value pair */
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                 /* found plugin name */
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                 /* found plugin database */
00364                 strncpy(tmp_entry->pluginargs,val,LCMAPS_MAXARGSTRING);
00365                 (tmp_entry->pluginargs)[LCMAPS_MAXARGSTRING]=NUL;
00366             }
00367             else
00368             {
00369                 /* unknown option: do nothing */
00370             }
00371         }
00372     }
00373 
00374     /* succes */
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     /* Skip over leading whitespace */
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         /* Cannot find '=' */
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         /* Found ' var =' and replace '=' with NUL*/
00434         *pair=NUL;
00435         if (! lcmaps_db_parse_string(&var))
00436         {
00437             /* error parsing variable name */
00438             return 0;
00439         }
00440         pair+=1;
00441         if (*pair==NUL)
00442         {
00443             /* No value found */
00444 /*            val=NULL; */
00445             val=pair;
00446             *pvar=var;
00447             *pval=val;
00448             return 1;
00449         }
00450         else
00451         {
00452             /* Skip over leading whitespace */
00453             pair += strspn(pair, WHITESPACE_CHARS);
00454             if (*pair == NUL)
00455             {
00456                 /* No value found */
00457 /*                val=NULL; */
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                 /* error parsing value */
00467                 return 0;
00468             }
00469         }
00470     }
00471     else
00472     {
00473         /* Cannot find '=' */
00474         lcmaps_log(0,"lcmaps.mod-lcmaps_db_parse_pair(): cannot find =\n");
00475         return 0;
00476     }
00477 
00478     /* success */
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     /* Is string quoted ? */
00510     if (strchr(QUOTING_CHARS, *string) != NULL)
00511     {
00512         /*
00513          * Yes, skip over opening quote and look for unescaped
00514          * closing double quote
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; /* Missing closing quote */
00525             }
00526 
00527             /* Make sure it's not escaped */
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     Function: lcmaps_db_clean_list
00543     documentation in _lcmaps_db_read.h
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     Function: lcmaps_db_clean
00576     documentation in _lcmaps_db_read.h
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 CVS Information:
00597     $Source: /cvs/fabric_mgt/gridification/lcmaps/src/pluginmanager/lcmaps_db_read.c,v $
00598     $Date: 2003/07/30 17:10:24 $
00599     $Revision: 1.5 $
00600     $Author: martijn $
00601 ******************************************************************************/

Generated at Thu Mar 4 17:39:03 2004 for edg-lcmaps by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001