blob: 22b6912884b4c0e2b4ffe67a79cc5890fe671774 [file] [log] [blame]
/*
** igmpproxy - IGMP proxy based multicast router
** Copyright (C) 2005 Johnny Egeland <johnny@rlo.org>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
**
**----------------------------------------------------------------------------
**
** This software is derived work from the following software. The original
** source code has been modified from it's original state by the author
** of igmpproxy.
**
** smcroute 0.92 - Copyright (C) 2001 Carsten Schill <carsten@cschill.de>
** - Licensed under the GNU General Public License, either version 2 or
** any later version.
**
** mrouted 3.9-beta3 - Copyright (C) 2002 by The Board of Trustees of
** Leland Stanford Junior University.
** - Licensed under the 3-clause BSD license, see Stanford.txt file.
**
*/
/**
* confread.c
*
* Generic config file reader. Used to open a config file,
* and read the tokens from it. The parser is really simple,
* and does no backlogging. This means that no form of
* text escaping and qouting is currently supported.
* '#' chars are read as comments, and the comment lasts until
* a newline or EOF
*
*/
#include "igmpproxy.h"
#define READ_BUFFER_SIZE 512 // Inputbuffer size...
#ifndef MAX_TOKEN_LENGTH
#define MAX_TOKEN_LENGTH 30 // Default max token length
#endif
FILE *confFilePtr; // File handle pointer
char *iBuffer; // Inputbuffer for reading...
unsigned int bufPtr; // Buffer position pointer.
unsigned int readSize; // Number of bytes in buffer after last read...
char cToken[MAX_TOKEN_LENGTH]; // Token buffer...
short validToken;
/**
* Opens config file specified by filename.
*/
int openConfigFile(char *filename) {
// Set the buffer to null initially...
iBuffer = NULL;
// Open the file for reading...
confFilePtr = fopen(filename, "r");
// On error, return false
if(confFilePtr == NULL) {
return 0;
}
// Allocate memory for inputbuffer...
iBuffer = (char*) malloc( sizeof(char) * READ_BUFFER_SIZE );
if(iBuffer == NULL) {
closeConfigFile();
return 0;
}
// Reset bufferpointer and readsize
bufPtr = 0;
readSize = 0;
return 1;
}
/**
* Closes the currently open config file.
*/
void closeConfigFile(void) {
// Close the file.
if(confFilePtr!=NULL) {
fclose(confFilePtr);
}
// Free input buffer memory...
if(iBuffer != NULL) {
free(iBuffer);
}
}
/**
* Returns the next token from the configfile. The function
* return NULL if there are no more tokens in the file.
*/
char *nextConfigToken(void) {
validToken = 0;
// If no file or buffer, return NULL
if(confFilePtr == NULL || iBuffer == NULL) {
return NULL;
}
{
unsigned int tokenPtr = 0;
unsigned short finished = 0;
unsigned short commentFound = 0;
// Outer buffer fill loop...
while ( !finished ) {
// If readpointer is at the end of the buffer, we should read next chunk...
if(bufPtr == readSize) {
// Fill up the buffer...
readSize = fread (iBuffer, sizeof(char), READ_BUFFER_SIZE, confFilePtr);
bufPtr = 0;
// If the readsize is 0, we should just return...
if(readSize == 0) {
return NULL;
}
}
// Inner char loop...
while ( bufPtr < readSize && !finished ) {
//printf("Char %s", iBuffer[bufPtr]);
// Break loop on \0
if(iBuffer[bufPtr] == '\0') {
break;
}
if( commentFound ) {
if( iBuffer[bufPtr] == '\n' ) {
commentFound = 0;
}
} else {
// Check current char...
switch(iBuffer[bufPtr]) {
case '#':
// Found a comment start...
commentFound = 1;
break;
case '\n':
case '\r':
case '\t':
case ' ':
// Newline, CR, Tab and space are end of token, or ignored.
if(tokenPtr > 0) {
cToken[tokenPtr] = '\0'; // EOL
finished = 1;
}
break;
default:
// Append char to token...
cToken[tokenPtr++] = iBuffer[bufPtr];
break;
}
}
// Check end of token buffer !!!
if(tokenPtr == MAX_TOKEN_LENGTH - 1) {
// Prevent buffer overrun...
cToken[tokenPtr] = '\0';
finished = 1;
}
// Next char...
bufPtr++;
}
// If the readsize is less than buffersize, we assume EOF.
if(readSize < READ_BUFFER_SIZE && bufPtr == readSize) {
if (tokenPtr > 0)
finished = 1;
else
return NULL;
}
}
if(tokenPtr>0) {
validToken = 1;
return cToken;
}
}
return NULL;
}
/**
* Returns the currently active token, or null
* if no tokens are available.
*/
char *getCurrentConfigToken(void) {
return validToken ? cToken : NULL;
}