#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netdb.h>
#include "config.h"

#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif

#include "wmnetmon.h"
#include "list.h"

static
int lineparser(char *line,char **tokens, int maxtokens, char *separators)
{
	char *stptr=line;
	int currenttoken;
	/* skip initial spaces and tabs */
	while ((*stptr)&&((*stptr)==' ' || (*stptr)=='\t'))
		stptr++;
	if ((*stptr) == 0) return -1; /* Empty line */
	if ((*stptr)=='#') return -1;
	tokens[0]=strtok(line,separators);
	currenttoken=1;
	
	while (currenttoken<maxtokens && 
		(tokens[currenttoken++] = strtok(NULL,separators)) );
	return 0;
}

static
int config_addhost(char **tok, pinger *p, hostmon **h)
{
	char *host;
	int tcpport = 0, udpport=0;
	
	if ((!tok[1]) || (!tok[2])) {
		fprintf(stderr,"Invalid number of args in rc file\n");
		return -1;
	}
	
	/* for TCP, the format is tcp/<port>@<host> */
	
	if (strncasecmp(tok[1],"tcp/",4) == 0) {
		char *portnum = tok[1] + 4;
		if ((host = strchr(portnum,'@'))) {
			*host=0; host++;
			tcpport = (int) strtoul ( portnum, (char**)NULL, 10 );
			if (tcpport ==0 || tcpport == LONG_MIN || tcpport == LONG_MAX) {
				struct servent *serv;
				/* Lookup the requested port */
				
				serv = getservbyname(portnum,"tcp");
				
				if (serv) {
					tcpport = ntohs(serv->s_port);
				} else {
					fprintf(stderr,"Invalid service: %s\n",
						portnum);
					perror("getservbyname");
					return -1 ;
				}
			}
		} 
	} 
	else
	if (strncasecmp(tok[1],"udp/",4) == 0) {
		char *portnum = tok[1] + 4;
		if ((host = strchr(portnum,'@'))) {
			*host=0; host++;
			udpport = (int) strtoul ( portnum, (char**)NULL, 10 );
			if (udpport ==0 || udpport == LONG_MIN || udpport == LONG_MAX) {
				struct servent *serv;
				/* Lookup the requested port */
				
				serv = getservbyname(portnum,"udp");
				
				if (serv) {
					udpport = ntohs(serv->s_port);
				} else {
					fprintf(stderr,"Invalid service: %s\n",
						portnum);
					perror("getservbyname");
					return -1 ;
				}
			}
		} 
	} 
	else 
	
	
	host=tok[1];
		
	(*h) = add_host( p, host, tok[2]);
	if (!(*h)) {
		fprintf(stderr,"Error in host\n");
		return -1;
	}
	
	(*h)->h->tcpport = tcpport;
	(*h)->h->udpport = udpport;
	
	if (tok[3]) {
		char *flag;
		for (flag=tok[3];*flag;flag++) 
		switch(*flag) {
			case 'd':
				(*h)->flags|=FLAG_DONTWARN;
				break;
			case 'w':
				(*h)->flags&=~FLAG_DONTWARN;
				break;
			case 'i':
				(*h)->flags|=FLAG_IGNORE_ON_MUTE;
				break;
			case 'm':
				(*h)->flags&=~FLAG_IGNORE_ON_MUTE;
				break;		
			default:
				fprintf(stderr,"Unknown flag '%c' in rc file\n",*flag);
				return -1;
		}
	}
	return 0;
}

int readconf(pinger *p, ledarray leds, char *fname)
{
	FILE *f;
	char configfile[128];
	char line[128];
	int neof,linecount=0;
	char *tok[4];
	hostmon *h;
	
	char *homedir=getenv("HOME");
	if (!homedir) {
                fprintf(stderr,"error: $HOME variable not set!\n\n");
                return -2;
        }

	if (! fname || ! (*fname)) 
		snprintf(configfile, 127, "%s/.wmnetmonrc",homedir);
	else
		snprintf(configfile, 127, "%s",fname);
	
	f=fopen(configfile,"r");
        if (!f) {
                fprintf(stderr,"%s not found\n",configfile);
                return -1;
        }
        do {
        	char *crlf;
        	int fail=0;
        	
        	*line=0;
		neof=fgets(line,128,f)!=0;
		linecount++;
		
		if ((crlf = strrchr(line,'\n')))
			(*crlf)=0;
			
		if (lineparser(line,tok,4,":") == 0) {
			if (strlen(tok[0]) > 1) {
				fprintf(stderr,"Error: invalid chars found at beginning of line %d\n",
				linecount);
				fclose( f );
				return -1;
			}
			switch(*tok[0]) {
				case 'H':
					if ( config_addhost(tok,p,&h) <0 ) fail++;
					break;
				case 'D':
					if (!tok[1]) {
						fprintf(stderr,
                                                "Invalid number of args in rc file, line %d",
                                                linecount);
						fclose( f );
                                                return -1;
					} else 
					{
						char *flag;
						for (flag=tok[1];*flag;flag++) {
							switch(*flag) {
								case 'w':
									default_flags &= ~ FLAG_DONTWARN;
									break;
								case 'd':
									default_flags |= FLAG_DONTWARN;
									break;
								case 'i':
									default_flags |= FLAG_IGNORE_ON_MUTE;
									break;
								case 'm':
									default_flags &= ~FLAG_IGNORE_ON_MUTE;
									break;
								default:
                                     					fprintf(stderr,
				                                     	"Unknown default flag '%c' in rc file, line %d\n",
                                				     	*flag,linecount);
									fclose( f );
                                     					return -1;	
							}
						}
					}					
					break;		
				case 'S':
					if (!tok[1]) {
						fprintf(stderr,
                                                "Invalid number of args in rc file, line %d",
                                                linecount);
								fclose( f );
								return -1;
					}
					strncpy(soundfile,tok[1],127);
					break;
				case 'P':
					if (!tok[1]) {
						fprintf(stderr,
										"Invalid number of args in rc file, line %d",
 linecount);
								fclose( f );
								return -1;
					}
					strncpy(soundplayer,tok[1],127);
					break;
					
				default:
					fprintf(stderr,
					"Unknown option '%c' in rc file\n",
					*tok[0]);
					fclose( f );
					return -1;
				
			}
			if (fail) {
				fprintf(stderr,"Aborting because of errors, line %d\n", 
				linecount);
				fclose( f );
				return -1;
			}
		}
	} while (neof);
	fclose(f);
	return 0;
}



syntax highlighted by Code2HTML, v. 0.9.1