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

lcas_db_read.c

Go to the documentation of this file.
00001 /*                                                                                                            
00002  * Copyright (c) Members of the EGEE Collaboration. 2004.
00003  * See http://eu-egee.org/partners/ for details on the copyright holders.
00004  * For license conditions see the license file or
00005  * http://eu-egee.org/license.html
00006  */
00007 
00008 /*                                                                                                            
00009  * Copyright (c) 2001 EU DataGrid.                                                                             
00010  * For license conditions see http://www.eu-datagrid.org/license.html                                          
00011  *
00012  * Copyright (c) 2001, 2002 by 
00013  *     Martijn Steenbakkers <martijn@nikhef.nl>,
00014  *     David Groep <davidg@nikhef.nl>,
00015  *     NIKHEF Amsterdam, the Netherlands
00016  */
00017 
00024 /*****************************************************************************
00025                             Include header files
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                                 Definitions
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  * Characters that terminate pairs, values and variables in the lcas database file. This
00053  * is a combination of whitespace and separators.
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                           Module specific prototypes
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                        Define module specific variables
00080 ******************************************************************************/
00081 static lcas_db_entry_t *  lcas_db_list=NULL; 
00083 /******************************************************************************
00084     Function: lcas_db_read
00085     documentation in _lcas_db_read.h
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         /* Cannot open file */
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 /*    lcas_db_fill_entry(no_entries,NULL); */
00142     while (fgets(line, sizeof(line), dbstream))
00143     {
00144         ++nlines;
00145 
00146         if (! lcas_db_parse_line(line, &entry))
00147         {
00148             /* parse error, return line number */
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             /* entry found */
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                 /* error filling lcas_db */
00165                 if (entry != NULL) free(entry);
00166                 return -(nlines);
00167             }
00168             if (entry != NULL) free(entry);
00169             entry=NULL;
00170         }
00171         else
00172         {
00173             /* no entry found, but no error */
00174             continue;
00175         }
00176     }
00177     if (entry != NULL) free(entry);
00178     return no_entries;
00179 }
00180 
00181 /******************************************************************************
00182     Function: lcas_db_fill_entry
00183     documentation in _lcas_db_read.h
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     /* Check arguments */
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     /* Skip over leading whitespace */
00269     line += strspn(line, WHITESPACE_CHARS);
00270 
00271     /* Check for comment at start of line and ignore line if present */
00272     if (strchr(COMMENT_CHARS, *line) != NULL) 
00273     {
00274         /* Ignore line, return NULL entry. */
00275         *entry=NULL;
00276         return 1;
00277     }
00278 
00279     /* Check for empty line */
00280     if (*line == NUL)
00281     {
00282         /* Empty line, return NULL entry. */
00283         *entry=NULL;
00284         return 1;
00285     }
00286 
00287     /* Look for variable-value pairs by checking the PAIR_SEP_CHARS */
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                 /* probably end of line */
00301                 continue;
00302             }
00303             if (strchr(PAIR_SEP_CHARS, *line) != NULL)
00304             {
00305                 *line=NUL;
00306                 line += 1;
00307             }
00308         }
00309         else
00310         {
00311             /* len = 0, so *line=PAIR_SEP_CHARS */
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                 /* error parsing variable-value pair */
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                 /* found plugin name */
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                 /* found plugin database */
00348                 strncpy(tmp_entry->pluginargs,val,LCAS_MAXARGSTRING);
00349                 (tmp_entry->pluginargs)[LCAS_MAXARGSTRING]=NUL;
00350             }
00351             else
00352             {
00353                 /* unknown option: do nothing */
00354             }
00355         }
00356     }
00357 
00358     /* succes */
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     /* Skip over leading whitespace */
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         /* Cannot find '=' */
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         /* Found ' var =' and replace '=' with NUL*/
00418         *pair=NUL;
00419         if (! lcas_db_parse_string(&var))
00420         {
00421             /* error parsing variable name */
00422             return 0;
00423         }
00424         pair+=1;
00425         if (*pair==NUL)
00426         {
00427             /* No value found */
00428 /*            val=NULL; */
00429             val=pair;
00430             *pvar=var;
00431             *pval=val;
00432             return 1;
00433         }
00434         else
00435         {
00436             /* Skip over leading whitespace */
00437             pair += strspn(pair, WHITESPACE_CHARS);
00438             if (*pair == NUL)
00439             {
00440                 /* No value found */
00441 /*                val=NULL; */
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                 /* error parsing value */
00451                 return 0;
00452             }
00453         }
00454     }
00455     else
00456     {
00457         /* Cannot find '=' */
00458         lcas_log(0,"lcas.mod-lcas_db_parse_pair(): cannot find =\n");
00459         return 0;
00460     }
00461 
00462     /* success */
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     /* Is string quoted ? */
00494     if (strchr(QUOTING_CHARS, *string) != NULL)
00495     {
00496         /*
00497          * Yes, skip over opening quote and look for unescaped
00498          * closing double quote
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; /* Missing closing quote */
00509             }
00510 
00511             /* Make sure it's not escaped */
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     Function: lcas_db_clean_list
00527     documentation in _lcas_db_read.h
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     Function: lcas_db_clean
00550     documentation in _lcas_db_read.h
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 CVS Information:
00564     $Source: /cvs/jra1mw/org.glite.security.lcas/src/lcas_db_read.c,v $
00565     $Date: 2004/10/14 16:05:27 $
00566     $Revision: 2.9 $
00567     $Author: msteenba $
00568 ******************************************************************************/

Generated on Fri May 27 18:10:48 2005 for lcas by doxygen 1.3.5