/*
* Copyright 2006 Pascal Gloor <pascal.gloor@spale.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "config.h"
#include "debug.h"
NFS_conf *load_config(char *file)
{
char buf[1000];
static NFS_conf conf;
FILE *fh = NULL;
int lno = 0;
conf.peer = 0;
if ( file == NULL )
{
fprintf(stderr,"impossible case. bug!? please report.\n");
goto fail;
}
if ( ( fh = fopen(file,"r") ) == NULL )
{
perror("fopen");
goto fail;
}
while(fgets(buf, sizeof(buf), fh)!=NULL)
{
char *token,*sip,*sp,*dip,*dp;
long int tmp;
lno++;
if ( buf[0] == '#' || buf[0] == ';' || buf[0] == '\r' || buf[0] == '\n' )
continue;
if ( ( token = strtok(buf,":") ) == NULL ) goto parse_err;
if ( strcmp(token,"flow") == 0 )
{
if ( conf.peer == MAXFLOW )
{
fprintf(stderr,"too many sources, please increase MAXFLOW !\n");
goto parse_err;
}
if ( ( sip = strtok(NULL,":") ) == NULL ) goto parse_err;
if ( ( sp = strtok(NULL,":") ) == NULL ) goto parse_err;
if ( ( dip = strtok(NULL,":") ) == NULL ) goto parse_err;
if ( ( dp = strtok(NULL,":\r\n\t ") ) == NULL ) goto parse_err;
conf.src[conf.peer].sin_family = AF_INET;
conf.dst[conf.peer].sin_family = AF_INET;
#ifdef inet_aton
if ( inet_aton(sip, &conf.src[conf.peer].sin_addr) == 0 ) goto parse_err;
if ( inet_aton(dip, &conf.dst[conf.peer].sin_addr) == 0 ) goto parse_err;
#else
if ( ( conf.src[conf.peer].sin_addr.s_addr = inet_addr(sip) ) == 0 ) goto parse_err;
if ( ( conf.dst[conf.peer].sin_addr.s_addr = inet_addr(dip) ) == 0 ) goto parse_err;
#endif
tmp = strtol(sp, NULL, 10);
if ( tmp < 0 || tmp > 65535 ) goto parse_err;
conf.srcif[conf.peer] = tmp;
tmp = strtol(dp, NULL, 10);
if ( tmp < 1 || tmp > 65535 ) goto parse_err;
conf.dst[conf.peer].sin_port = htons(tmp);
debug(printf("config: peer %i: input from device %s interface %i",conf.peer,inet_ntoa(conf.src[conf.peer].sin_addr), conf.srcif[conf.peer]));
debug(printf("config: peer %i: output to %s:%i",conf.peer,inet_ntoa(conf.dst[conf.peer].sin_addr), ntohs(conf.dst[conf.peer].sin_port)));
conf.peer++;
}
else if ( strcmp(buf,"local") == 0 )
{
if ( ( dip = strtok(NULL,":") ) == NULL ) goto parse_err;
if ( ( dp = strtok(NULL,":\r\n\t ") ) == NULL ) goto parse_err;
#ifdef inet_aton
if ( inet_aton(dip, &conf.sock.sin_addr) == 0 ) goto parse_err;
#else
if ( ( conf.sock.sin_addr.s_addr = inet_addr(dip) ) == 0 ) goto parse_err;
#endif
tmp = strtol(dp, NULL, 10);
if ( tmp < 1 || tmp > 65535 ) goto parse_err;
conf.sock.sin_port = htons(tmp);
debug(printf("config: listener %s:%i",inet_ntoa(conf.sock.sin_addr),ntohs(conf.sock.sin_port)));
}
else
goto parse_err;
}
if ( !feof(fh) )
{
fprintf(stderr,"I/O error while reading config.\n");
goto fail;
}
goto ok;
parse_err:
fprintf(stderr,"config parse error at line %i.\n",lno);
fail:
if ( fh != NULL ) fclose(fh);
return NULL;
ok:
fclose(fh);
return &conf;
}