From 4166da2f2b4a1633ccf45f83ef21765f1a9cdf46 Mon Sep 17 00:00:00 2001 From: reenoo Date: Sun, 28 Dec 2003 23:47:30 +0000 Subject: [PATCH] Fixed crashes due to use of nested functions. I have therefore added shared/fileio.c/h to encapsule buffered file operations, thus making it possible to re-read the configuration file unlike with the patch I committed to stable-0-4-4. See also: http://lists.omnipotent.net/pipermail/lcdproc/2003-December/008413.html --- shared/configfile.c | 44 +++++++++++------------- shared/fileio.c | 82 +++++++++++++++++++++++++++++++++++++++++++++ shared/fileio.h | 40 ++++++++++++++++++++++ 3 files changed, 141 insertions(+), 25 deletions(-) create mode 100644 shared/fileio.c create mode 100644 shared/fileio.h diff --git a/shared/configfile.c b/shared/configfile.c index cbf0907..62df619 100644 --- a/shared/configfile.c +++ b/shared/configfile.c @@ -25,6 +25,7 @@ #endif /* WITH_LDAP_SUPPORT */ #include "shared/report.h" +#include "shared/fileio.h" typedef struct key { @@ -48,7 +49,8 @@ section * find_section( char * sectionname ); section * add_section( char * sectionname ); key * find_key( section * s, char * keyname, int skip ); key * add_key( section * s, char * keyname, char * value ); -int process_config( section ** current_section, char (*get_next_char)(), char modify_section_allowed, char * source_descr ); +char get_next_char_f(buffile * f); +int process_config( section ** current_section, char (*get_next_char)(), char modify_section_allowed, char * source_descr, buffile * f ); #ifdef WITH_LDAP_SUPPORT int connect_to_ldap(void); @@ -67,14 +69,9 @@ int ldap_port; /**** EXTERNAL FUNCTIONS ****/ -#define FILECHUNKSIZE 10 - int config_read_file( char *filename ) { - FILE * f; - char buf[FILECHUNKSIZE]; - int bytesread=0; - int pos=0; + buffile * f; section * curr_section = NULL; #ifdef WITH_LDAP_SUPPORT @@ -112,26 +109,14 @@ int config_read_file( char *filename ) } #endif /* WITH_LDAP_SUPPORT */ - /* We use a nested fuction to transfer the characters from buffer to parser*/ - char get_next_char() { - if( pos>=bytesread ) { - if( !( bytesread = fread( buf, 1, FILECHUNKSIZE, f ))) { - /* We're at the end*/ - return 0; - } - pos = 0; - } - return buf[pos++]; - } - - f = fopen( filename, "r" ); + f = buffile_open( filename, "r" ); if( f==NULL ) { return -1; } - process_config( &curr_section, get_next_char, 1, filename ); + process_config( &curr_section, get_next_char_f, 1, filename, f ); - fclose( f ); + buffile_close( f ); return 0; } @@ -152,7 +137,7 @@ int config_read_string( char *sectionname, char *str ) s=add_section( sectionname ); } - process_config( &s, get_next_char, 0, "command line" ); + process_config( &s, get_next_char, 0, "command line", NULL ); return 0; } @@ -565,6 +550,10 @@ key * add_key( section * s, char * keyname, char * value ) return (*place); } +char get_next_char_f(buffile * f) { + return ((char) buffile_read(f, 1)[0]); +} + /* Parser states*/ #define ST_INITIAL 0 @@ -587,7 +576,7 @@ key * add_key( section * s, char * keyname, char * value ) -int process_config( section ** current_section, char (*get_next_char)(), char modify_section_allowed, char * source_descr ) +int process_config( section ** current_section, char (*get_next_char)(), char modify_section_allowed, char * source_descr, buffile * f) { char state = ST_INITIAL; char ch; @@ -603,7 +592,12 @@ int process_config( section ** current_section, char (*get_next_char)(), char mo while( state != ST_END ) { - ch = get_next_char(); + if (NULL != f) { + ch = get_next_char(f); + } + else { + ch = get_next_char(); + } /* Secretly keep count of the line numbers*/ if( ch == '\n' ) { diff --git a/shared/fileio.c b/shared/fileio.c new file mode 100644 index 0000000..6b3ba70 --- /dev/null +++ b/shared/fileio.c @@ -0,0 +1,82 @@ +/* + * fileio.c + * This file is part of LCDd, the lcdproc server. + * + * This file is released under the GNU General Public License. Refer to the + * COPYING file distributed with this package. + * + * Copyright (c) 2003, Rene Wagner + * + * + * Defines routines to read from buffered files. + * + */ + +#include +#include +#include "fileio.h" + +#define FILECHUNKSIZE 10 + +buffile *buffile_open( const char *path, const char *mode ) { + buffile * file = NULL; + + file = malloc(sizeof(*file)); + if ( NULL == file ) + return NULL; + + file->pos=0; + file->bytesread=0; + + file->f = fopen( path, mode ); + if( NULL == file->f ) { + free(file); + return NULL; + } + + return file; +} + +int buffile_close ( buffile * file ) { + int retval=0; + + if (NULL == file) + return -1; + if ( NULL != file->f ) + retval = fclose( file->f ); + if ( NULL != file->buf ) + free ( file->buf ); + free (file); + file = NULL; + + return retval; +} + +char * buffile_read ( buffile * file, size_t n ) { + char * returnbuf=NULL; + + if( NULL == file ) + return NULL; + + returnbuf = malloc(n); + if( NULL == returnbuf) + return NULL; + + if( NULL == file->buf ) { + file->buf = malloc(FILECHUNKSIZE); + if( NULL == file->buf ) + return NULL; + } + + if( file->pos >= file->bytesread ) { + if( !( file->bytesread = fread( file->buf, 1, FILECHUNKSIZE, file->f ))) { + /* We're at the end*/ + returnbuf[0]=0; + return returnbuf; + } + file->pos = 0; + } + strncpy(returnbuf, file->buf + (file->pos++), sizeof(returnbuf)); + return returnbuf; +} + diff --git a/shared/fileio.h b/shared/fileio.h new file mode 100644 index 0000000..1ccb827 --- /dev/null +++ b/shared/fileio.h @@ -0,0 +1,40 @@ +/* + * fileio.h + * This file is part of LCDd, the lcdproc server. + * + * This file is released under the GNU General Public License. Refer to the + * COPYING file distributed with this package. + * + * Copyright (c) 2003, Rene Wagner + * + * + * Defines routines to read from buffered files. + * + */ + +#ifndef FILEIO_H +#define FILEIO_H + +#include + +typedef struct buffile { + FILE * f; + char * buf; + int bytesread, pos; +} buffile; + +buffile *buffile_open( const char *path, const char *mode ); +/* Opens the given file and returns a pointer to the corresponding + * buffile object. + */ +int buffile_close ( buffile * file ); +/* Tries to close the file corresponding to the given buffile + * object and to free the memory used by the buffile object itself. + * Returns 0 on success, return value of fclose(3) in case of errors + * with fclose. + */ +char * buffile_read ( buffile * file, size_t n ); +/* Reads n bytes from the given buffile object. + */ + +#endif