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) 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 "lcas_log.h"
00025 #include "_lcas_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 lcas 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 lcas_db_read_entries(FILE *);
00067 static int lcas_db_parse_line(char *, lcas_db_entry_t **);
00068 static int lcas_db_parse_pair(char *, char **, char **);
00069 static int lcas_db_parse_string(char **);
00070 
00071 /******************************************************************************
00072                        Define module specific variables
00073 ******************************************************************************/
00074 static lcas_db_entry_t *  lcas_db_list=NULL; 
00076 /******************************************************************************
00077     Function: lcas_db_read
00078     documentation in _lcas_db_read.h
00079 ******************************************************************************/
00080 lcas_db_entry_t ** lcas_db_read(
00081         char * lcas_db_fname
00082 )
00083 {
00084     FILE * lcas_db_fhandle;
00085     int    no_entries;
00086 
00087     lcas_db_fhandle = fopen(lcas_db_fname, "r");
00088     if (lcas_db_fhandle == NULL)
00089     {
00090         /* Cannot open file */
00091         return NULL;
00092     }
00093 
00094     no_entries=lcas_db_read_entries(lcas_db_fhandle);
00095     if (no_entries < 0)
00096     {
00097         lcas_log(0,"lcas.mod-lcas_db_read(): Parse error in line %d of %s\n",
00098             -(no_entries), lcas_db_fname);
00099         fclose(lcas_db_fhandle);
00100         return NULL;
00101     }
00102     else if (no_entries > MAXDBENTRIES)
00103     {
00104         lcas_log(0,"lcas.mod-lcas_db_read(): Too many entries found in %s\n",
00105             lcas_db_fname);
00106         lcas_log(0,"lcas.mod-lcas_db_read(): Only the first %d entries are used\n",
00107             MAXDBENTRIES);
00108     }
00109     fclose(lcas_db_fhandle);
00110 
00111     return &lcas_db_list;
00112 }
00113 
00123 static int lcas_db_read_entries(
00124         FILE * dbstream
00125 )
00126 {
00127     char               line[1024];
00128     int                nlines=0;
00129     int                no_entries=0;
00130     lcas_db_entry_t *  entry=NULL;
00131 
00132     nlines=0;
00133     no_entries=0;
00134 /*    lcas_db_fill_entry(no_entries,NULL); */
00135     while (fgets(line, sizeof(line), dbstream))
00136     {
00137         ++nlines;
00138 
00139         if (! lcas_db_parse_line(line, &entry))
00140         {
00141             /* parse error, return line number */
00142             if (entry != NULL) free(entry);
00143             return -(nlines);
00144         }
00145         if (entry != NULL)
00146         {
00147             lcas_log_debug(3,"line %d: %s, %s\n",nlines,entry->pluginname,entry->pluginargs);
00148             /* entry found */
00149             ++no_entries;
00150             if (no_entries > MAXDBENTRIES)
00151             {
00152                 if (entry != NULL) free(entry);
00153                 return no_entries;
00154             }
00155             if ( lcas_db_fill_entry(&lcas_db_list, entry)==NULL )
00156             {
00157                 /* error filling lcas_db */
00158                 if (entry != NULL) free(entry);
00159                 return -(nlines);
00160             }
00161             if (entry != NULL) free(entry);
00162             entry=NULL;
00163         }
00164         else
00165         {
00166             /* no entry found, but no error */
00167             continue;
00168         }
00169     }
00170     if (entry != NULL) free(entry);
00171     return no_entries;
00172 }
00173 
00174 /******************************************************************************
00175     Function: lcas_db_fill_entry
00176     documentation in _lcas_db_read.h
00177 ******************************************************************************/
00178 lcas_db_entry_t * lcas_db_fill_entry(
00179         lcas_db_entry_t ** list,
00180         lcas_db_entry_t * entry
00181 )
00182 {
00183     lcas_db_entry_t * plist;
00184 
00185     if (entry == NULL)
00186     {
00187         lcas_log(0,"lcas.mod-lcas_db_fill_entry(): error null entry\n");
00188         return NULL;
00189     }
00190 
00191     if (!(*list))
00192     {
00193         lcas_log_debug(2,"lcas.mod-lcas_db_fill_entry(): creating first list entry\n");
00194         *list=plist=(lcas_db_entry_t *)malloc(sizeof(lcas_db_entry_t));
00195     }
00196     else
00197     {
00198         lcas_log_debug(2,"lcas.mod-lcas_db_fill_entry(): creating new list entry\n");
00199         plist=*list;
00200         while (plist->next) plist=plist->next;
00201         plist=plist->next=(lcas_db_entry_t *)malloc(sizeof(lcas_db_entry_t));
00202     }
00203     if (!plist)
00204     {
00205         lcas_log(0,"lcas.mod-lcas_db_fill_entry(): error creating new list entry\n");
00206         return NULL;
00207     }
00208     plist->next=NULL;
00209 
00210     if (entry->pluginname != NULL)
00211     {
00212         strncpy(plist->pluginname,entry->pluginname,LCAS_MAXPATHLEN);
00213         (plist->pluginname)[LCAS_MAXPATHLEN]=NUL;
00214     }
00215     else
00216         strncpy(plist->pluginname,"",LCAS_MAXPATHLEN);
00217 
00218     if (entry->pluginargs != NULL)
00219     {
00220         strncpy(plist->pluginargs,entry->pluginargs,LCAS_MAXARGSTRING);
00221         (plist->pluginargs)[LCAS_MAXARGSTRING]=NUL;
00222     }
00223     else
00224         strncpy(plist->pluginargs,"",LCAS_MAXARGSTRING);
00225 
00226     return plist;
00227 }
00228 
00241 static int lcas_db_parse_line(
00242         char * line,
00243         lcas_db_entry_t ** entry
00244 )
00245 {
00246     char *            var_val_pairs[MAXPAIRS];
00247     char *            var;
00248     char *            val;
00249     int               ipair;
00250     int               no_pairs;
00251     size_t            len;
00252     lcas_db_entry_t * tmp_entry=NULL;
00253 
00254     /* Check arguments */
00255     if ((line == NULL) || (*entry != NULL))
00256     {
00257         lcas_log(0,"lcas.mod-lcas_db_parse_line(): something wrong with arguments\n");
00258         goto error;
00259     }
00260 
00261     /* Skip over leading whitespace */
00262     line += strspn(line, WHITESPACE_CHARS);
00263 
00264     /* Check for comment at start of line and ignore line if present */
00265     if (strchr(COMMENT_CHARS, *line) != NULL) 
00266     {
00267         /* Ignore line, return NULL entry. */
00268         *entry=NULL;
00269         return 1;
00270     }
00271 
00272     /* Check for empty line */
00273     if (*line == NUL)
00274     {
00275         /* Empty line, return NULL entry. */
00276         *entry=NULL;
00277         return 1;
00278     }
00279 
00280     /* Look for variable-value pairs by checking the PAIR_SEP_CHARS */
00281     ipair=0;
00282     len=0;
00283     while (*line != NUL)
00284     {
00285         len=strcspn(line, PAIR_SEP_CHARS);
00286         if (len > 0)
00287         {
00288             var_val_pairs[ipair] = line;
00289             ipair++;
00290             line+=len;
00291             if (*line == NUL)
00292             {
00293                 /* probably end of line */
00294                 continue;
00295             }
00296             if (strchr(PAIR_SEP_CHARS, *line) != NULL)
00297             {
00298                 *line=NUL;
00299                 line += 1;
00300             }
00301         }
00302         else
00303         {
00304             /* len = 0, so *line=PAIR_SEP_CHARS */
00305             line += 1;
00306         }
00307         line += strspn(line, WHITESPACE_CHARS);
00308     }
00309     no_pairs=ipair;
00310     if (no_pairs)
00311     {
00312         tmp_entry=malloc(sizeof(*tmp_entry));
00313         if (tmp_entry == NULL)
00314         {
00315             lcas_log(0,"lcas.mod-lcas_db_parse_line(): error allocating memory\n");
00316             goto error;
00317         }
00318 
00319         for (ipair=0; ipair < no_pairs; ipair++)
00320         {
00321             int rc=0;
00322             lcas_log_debug(3,"pair %d:%s-endpair\n",ipair, var_val_pairs[ipair]);
00323             rc=lcas_db_parse_pair(var_val_pairs[ipair], &var, &val);
00324             if (! rc)
00325             {
00326                 /* error parsing variable-value pair */
00327                 lcas_log(0,"lcas.mod-lcas_db_parse_line(): error parsing variable-value pair\n");
00328                 goto error;
00329             }
00330             lcas_log_debug(3,"var: %s, value: %s\n",var,val);
00331 
00332             if (strncmp(var,"pluginname",strlen("pluginname")) == 0)
00333             {
00334                 /* found plugin name */
00335                 strncpy(tmp_entry->pluginname,val,LCAS_MAXPATHLEN);
00336                 (tmp_entry->pluginname)[LCAS_MAXPATHLEN]=NUL;
00337             }
00338             else if (strncmp(var,"pluginargs",strlen("pluginargs")) == 0)
00339             {
00340                 /* found plugin database */
00341                 strncpy(tmp_entry->pluginargs,val,LCAS_MAXARGSTRING);
00342                 (tmp_entry->pluginargs)[LCAS_MAXARGSTRING]=NUL;
00343             }
00344             else
00345             {
00346                 /* unknown option: do nothing */
00347             }
00348         }
00349     }
00350 
00351     /* succes */
00352     *entry=tmp_entry;
00353     return 1;
00354 
00355   error:
00356     if (tmp_entry != NULL) free(tmp_entry);
00357     return 0;
00358 }
00359 
00374 static int lcas_db_parse_pair(
00375         char * pair,
00376         char ** pvar,
00377         char ** pval
00378 )
00379 {
00380     int    len;
00381     char * var;
00382     char * val;
00383 
00384     if (pair == NULL)
00385     {
00386         lcas_log(0,"lcas.mod-lcas_db_parse_pair(): cannot parse empty pair\n");
00387         return 0;
00388     }
00389 
00390     /* Skip over leading whitespace */
00391     pair += strspn(pair, WHITESPACE_CHARS);
00392     if (*pair == NUL)
00393     {
00394         lcas_log(0,"lcas.mod-lcas_db_parse_pair(): cannot parse empty pair\n");
00395         return 0;
00396     }
00397 
00398     var=pair;
00399     len=strcspn(pair, VARVAL_SEP_CHARS);
00400     pair+=len;
00401     if (*pair == NUL)
00402     {
00403         /* Cannot find '=' */
00404         lcas_log(0,"lcas.mod-lcas_db_parse_pair(): cannot find =\n");
00405         return 0;
00406     }
00407 
00408     if (strchr(VARVAL_SEP_CHARS, *pair) != NULL)
00409     {
00410         /* Found ' var =' and replace '=' with NUL*/
00411         *pair=NUL;
00412         if (! lcas_db_parse_string(&var))
00413         {
00414             /* error parsing variable name */
00415             return 0;
00416         }
00417         pair+=1;
00418         if (*pair==NUL)
00419         {
00420             /* No value found */
00421 /*            val=NULL; */
00422             val=pair;
00423             *pvar=var;
00424             *pval=val;
00425             return 1;
00426         }
00427         else
00428         {
00429             /* Skip over leading whitespace */
00430             pair += strspn(pair, WHITESPACE_CHARS);
00431             if (*pair == NUL)
00432             {
00433                 /* No value found */
00434 /*                val=NULL; */
00435                 val=pair;
00436                 *pvar=var;
00437                 *pval=val;
00438                 return 1;
00439             }
00440             val=pair;
00441             if (! lcas_db_parse_string(&val))
00442             {
00443                 /* error parsing value */
00444                 return 0;
00445             }
00446         }
00447     }
00448     else
00449     {
00450         /* Cannot find '=' */
00451         lcas_log(0,"lcas.mod-lcas_db_parse_pair(): cannot find =\n");
00452         return 0;
00453     }
00454 
00455     /* success */
00456     *pvar=var;
00457     *pval=val;
00458     return 1;
00459 }
00460 
00471 static int lcas_db_parse_string(
00472         char ** pstring
00473 )
00474 {
00475     char * end;
00476     char * string;
00477 
00478     string=*pstring;
00479 
00480     if (*string==NUL)
00481     {
00482         lcas_log(0,"lcas.mod-lcas_db_parse_string(): error parsing null string\n");
00483         return 0;
00484     }
00485 
00486     /* Is string quoted ? */
00487     if (strchr(QUOTING_CHARS, *string) != NULL)
00488     {
00489         /*
00490          * Yes, skip over opening quote and look for unescaped
00491          * closing double quote
00492          */
00493         string++;
00494         end=string;
00495         do
00496         {
00497             end += strcspn(end, QUOTING_CHARS);
00498             if (*end == NUL)
00499             {
00500                 lcas_log(0,"lcas.mod-lcas_db_parse_string(): missing closing quote\n");
00501                 return 0; /* Missing closing quote */
00502             }
00503 
00504             /* Make sure it's not escaped */
00505         }
00506         while (strchr(ESCAPING_CHARS, *(end - 1)) != NULL);
00507     }
00508     else
00509     {
00510         end = string + strcspn(string, WHITESPACE_CHARS);
00511     }
00512     *end=NUL;
00513     *pstring=string;
00514 
00515     return 1;
00516 }
00517 
00518 /******************************************************************************
00519     Function: lcas_db_clean_list
00520     documentation in _lcas_db_read.h
00521 ******************************************************************************/
00522 int lcas_db_clean_list(
00523         lcas_db_entry_t ** list
00524 )
00525 {
00526     lcas_db_entry_t * entry;
00527 
00528     entry=*list;
00529     while (entry)
00530     {
00531         lcas_db_entry_t * next_entry;
00532         lcas_log_debug(2,"cleaning db entry for module %s\n",entry->pluginname);
00533         next_entry=entry->next;
00534         free(entry);
00535         entry=next_entry;
00536     }
00537     *list=entry=NULL;
00538     return 0;
00539 }
00540 
00541 /******************************************************************************
00542     Function: lcas_db_clean
00543     documentation in _lcas_db_read.h
00544 ******************************************************************************/
00545 int lcas_db_clean()
00546 {
00547     if(lcas_db_clean_list(&lcas_db_list) != 0)
00548     {
00549         lcas_log(0,"lcas.mod-lcas_db_clean() error: could not clean list\n");
00550         return 1;
00551     }
00552     return 0;
00553 }
00554 
00555 /******************************************************************************
00556 CVS Information:
00557     $Source: /cvs/fabric_mgt/gridification/lcas/src/lcas_db_read.c,v $
00558     $Date: 2003/08/15 13:24:35 $
00559     $Revision: 2.8 $
00560     $Author: martijn $
00561 ******************************************************************************/

Generated at Tue Sep 23 15:06:52 2003 for edg-lcas by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001