/* liveice.c
 *
 * Copyright (c) 1999 Scott Manley, Barath Raghavan, Jack Moffitt, and Alexander Haväng
 *
 * 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.
 *
 */


#include "liveice.h"
/* all the configuration stuff sits in this file */ 


/* default names */
char sound_pipe_name[]          = "raw.pipe";
char mpeg_pipe_name[]           = "mpeg.pipe";
char default_server[]           = "localhost";
char default_playlist[]         = "playlist";
char default_password[]         = "letmein";
char default_icy_name[]         = "LiveIce";
char default_icy_genre[]        = "live";
char default_icy_url[]          = "localhost";
char default_mix_control_file[] = "mix_command";
char default_decoder_cmd[]      = "mpg123";
char default_track_logfile[]    = "tracks.log";
char default_mountpoint[]       = "liveice";
char default_description[]      = "LiveIce";
char default_pipe_directory[]   = ".liveice_temp_files";
char default_sound_input_file[] = "/dev/dsp";

/* default encoder commands */
char AJ_encoder_command[]       = "encoder";
char L3ENC_encoder_command[]    = "l3enc";
char MP3ENC_encoder_command[]   = "mp3enc";
char SCREAMER_encoder_command[] = "lamer";
char XING_encoder_command[]     = "xingmp3enc";
char LAME3_encoder_command[]    = "lame3";
char GOGO_encoder_command[]    = "gogo";

static int in_stream_set;
static int default_sample_rate;
static int default_stereo;

void string_copy(char **strp, char *str){
	if(*strp !=NULL) {
		free(*strp);
	}
	*strp = malloc(strlen(str)+2);
	strcpy(*strp,str);
} 

void copy_defaults_to_stream(enc_struct *e_stream){
	if(!in_stream_set) {
		  default_sample_rate=g_conf.sample_rate;
		  default_stereo=g_conf.stereo ? 1 : 0;
	}
  	e_stream->enabled     = 1;    
	e_stream->port        = g_conf.port;
	string_copy(&(e_stream->encoder_cmd),g_conf.encoder_cmd);
	string_copy(&(e_stream->server),g_conf.server);
	string_copy(&(e_stream->password),g_conf.password);
	string_copy(&(e_stream->mountpoint),g_conf.mountpoint);
	string_copy(&(e_stream->name),g_conf.icy_name);
	string_copy(&(e_stream->genre),g_conf.icy_genre);
	string_copy(&(e_stream->url),g_conf.icy_url);
	string_copy(&(e_stream->description),g_conf.description);
	/* filename to dump the recording to */
	e_stream->recording_file=g_conf.recording_file;
	e_stream->remote_dumpfile=g_conf.remote_dumpfile;
	e_stream->encoder_args=g_conf.encoder_args;
	
	e_stream->encoder     = g_conf.encoder;
	e_stream->public      = g_conf.icy_public;
	e_stream->bitrate     = g_conf.bitrate;
	e_stream->vbr_quality = g_conf.vbr_quality;
	e_stream->encoding_quality = g_conf.encoding_quality;
	e_stream->sample_rate = g_conf.sample_rate;;
	e_stream->stereo      = g_conf.stereo;
	e_stream->header_format = g_conf.header_format;
	e_stream->copyright   = g_conf.copyright;  
}


/* copy the entry into the global configuration */
void copy_stream_to_defaults(enc_struct *e_stream){
	g_conf.port=e_stream->port;
	g_conf.sample_rate=e_stream->sample_rate;
	g_conf.encoder=e_stream->encoder;
	g_conf.icy_public=e_stream->public;
	g_conf.bitrate=e_stream->bitrate;
	g_conf.vbr_quality=e_stream->vbr_quality;
	g_conf.encoding_quality=e_stream->encoding_quality;
	g_conf.stereo=e_stream->stereo;
	g_conf.header_format=e_stream->header_format;
	g_conf.copyright=e_stream->copyright;
	g_conf.recording_file=e_stream->recording_file;
	g_conf.remote_dumpfile=e_stream->remote_dumpfile;
	g_conf.encoder_args=e_stream->encoder_args;


	if(g_conf.description!=default_description)
		free(g_conf.description);
	g_conf.description=malloc(strlen(e_stream->description)+2);
	strcpy(g_conf.description,e_stream->description);
	
	if(g_conf.icy_genre!=default_icy_genre)
		free(g_conf.icy_genre);
	g_conf.icy_genre=malloc(strlen(e_stream->genre)+2);
	strcpy(g_conf.icy_genre,e_stream->genre);
	
	if(g_conf.mountpoint!=default_mountpoint)
		free(g_conf.mountpoint);
	g_conf.mountpoint=malloc(strlen(e_stream->mountpoint)+2);
	strcpy(g_conf.mountpoint,e_stream->mountpoint);

	if(g_conf.icy_name!=default_icy_name)
		free(g_conf.icy_name);
	g_conf.icy_name=malloc(strlen(e_stream->name)+2);
	strcpy(g_conf.icy_name,e_stream->name);

	if(g_conf.password!=default_password)
		free(g_conf.password);
	g_conf.password=malloc(strlen(e_stream->password)+2);
	strcpy(g_conf.password,e_stream->password);

	if(g_conf.server!=default_server)
		free(g_conf.server);
	g_conf.server=malloc(strlen(e_stream->server)+2);
	strcpy(g_conf.server,e_stream->server);
	
	if(g_conf.icy_url!=default_icy_url)
		free(g_conf.icy_url);
	g_conf.icy_url=malloc(strlen(e_stream->url)+2);
	strcpy(g_conf.icy_url,e_stream->url);

	free(g_conf.encoder_cmd);
	g_conf.encoder_cmd=malloc(strlen(e_stream->encoder_cmd)+2);
	strcpy(g_conf.encoder_cmd,e_stream->encoder_cmd);

}

void default_encoder_stream(enc_struct *e_stream,int i){
	e_stream->enabled=0;    /* disable by default - becomed pid */
	e_stream->port=PORT;

	/* set all the strings to NULL if they're not being used */
	e_stream->server=NULL;
	e_stream->password=NULL;
	e_stream->mountpoint=NULL;
	e_stream->name=NULL;
	e_stream->genre=NULL;
	e_stream->url=NULL;
	e_stream->description=NULL;

	e_stream->sound_pipe  = malloc(strlen(sound_pipe_name)+4);
	sprintf(e_stream->sound_pipe,"%s%d",sound_pipe_name,i);

	e_stream->mpeg_pipe   = malloc(strlen(mpeg_pipe_name)+4);
	sprintf(e_stream->mpeg_pipe,"%s%d",mpeg_pipe_name,i);

	e_stream->encoder_cmd=NULL;	
	e_stream->recording_file=NULL;
	e_stream->remote_dumpfile=NULL;
	e_stream->encoder_args=NULL;

	e_stream->public=1;
	e_stream->bitrate=BITRATE;
	e_stream->vbr_quality=VBR_QUALITY;
	e_stream->encoding_quality=ENCODING_QUALITY;
	e_stream->sample_rate=SAMPLE_RATE;
	e_stream->stereo=0;
	e_stream->header_format=0;
	e_stream->copyright=0;
	e_stream->encoder=DEFAULT_ENCODER;  
	e_stream->pipe=NULL;  
	e_stream->enc=0;
	e_stream->tcp=0;
}



void default_config(void){
	int i;
	time_t now;
	/*defaults */
	for(i=0;i<MAX_ENCODER_STREAMS;i++){
		default_encoder_stream(&(g_conf.e_str[i]),i);
	}
	g_conf.port=PORT;
	g_conf.server=malloc(strlen(default_server)+2);
	strcpy(g_conf.server,default_server);
	
	g_conf.playlist=malloc(strlen(default_playlist)+2);
	strcpy(g_conf.playlist,default_playlist);
	
       	g_conf.password=malloc(strlen(default_password)+2);
	strcpy(g_conf.password,default_password);

	g_conf.icy_name=malloc(strlen(default_icy_name)+2);
	strcpy(g_conf.icy_name,default_icy_name);

	g_conf.icy_genre=malloc(strlen(default_icy_genre)+2);
	strcpy(g_conf.icy_genre,default_icy_genre);

	g_conf.track_logfile=malloc(strlen(LOGDIR) + strlen(default_track_logfile)+2);
	strcpy(g_conf.track_logfile, LOGDIR);
	g_conf.track_logfile = strcat(g_conf.track_logfile, default_track_logfile);

	g_conf.logfile_format=NULL;
	g_conf.recording_file=NULL;
	g_conf.remote_dumpfile=NULL;
	g_conf.encoder_args=NULL;
	
	g_conf.icy_url=malloc(strlen(default_icy_url)+2);
	strcpy(g_conf.icy_url,default_icy_url);

	g_conf.decoder_cmd=malloc(strlen(default_decoder_cmd)+2);
	strcpy(g_conf.decoder_cmd,default_decoder_cmd);

	g_conf.mountpoint=malloc(strlen(default_mountpoint)+2);
	strcpy(g_conf.mountpoint,default_mountpoint);

	g_conf.description=malloc(strlen(default_description)+2);
	strcpy(g_conf.description,default_description);

	g_conf.pipe_dir=malloc(strlen(default_pipe_directory)+2);
	strcpy(g_conf.pipe_dir,default_pipe_directory);

	g_conf.mix_control_file=malloc(strlen(default_mix_control_file)+2);
	strcpy(g_conf.mix_control_file,default_mix_control_file);
	
	g_conf.sound_input_file=malloc(strlen(default_sound_input_file)+2);
	strcpy(g_conf.sound_input_file,default_sound_input_file);


	g_conf.icy_public=1;
	g_conf.bitrate=BITRATE;
	g_conf.vbr_quality=VBR_QUALITY;
	g_conf.sample_rate=SAMPLE_RATE; 
	g_conf.sound_device=1;
	g_conf.stereo=0;
	g_conf.full_duplex=0;
	g_conf.soundcard=1;         
	g_conf.hacked_decoder=0;
	g_conf.header_format=0;
	g_conf.frontend=FE_CURSES;
	g_conf.encoding_quality=ENCODING_QUALITY;
	g_conf.end_time=0;
	g_conf.meta_data=0;

	g_conf.encoder=DEFAULT_ENCODER;
#if DEFAULT_ENCODER==L3ENC
	g_conf.encoder_cmd=malloc(strlen(L3ENC_encoder_command)+2);
	strcpy(g_conf.encoder_cmd,L3ENC_encoder_command);
#elif DEFAULT_ENCODER==MP3ENC
	g_conf.encoder_cmd=malloc(strlen(MP3ENC_encoder_command)+2);
	strcpy(g_conf.encoder_cmd,MP3ENC_encoder_command);
#elif DEFAULT_ENCODER==AJ_ENCODER
	g_conf.encoder_cmd=malloc(strlen(AJ_encoder_command)+2);
	strcpy(g_conf.encoder_cmd,AJ_encoder_command);
#elif DEFAULT_ENCODER==SCREAMER
	g_conf.encoder_cmd=malloc(strlen(SCREAMER_encoder_command)+2);
	strcpy(g_conf.encoder_cmd,SCREAMER_encoder_command);
#elif DEFAULT_ENCODER==XING
	g_conf.encoder_cmd=malloc(strlen(XING_encoder_command)+2);
	strcpy(g_conf.encoder_cmd,XING_encoder_command);
#elif DEFAULT_ENCODER==XING_VBR
	g_conf.encoder_cmd=malloc(strlen(XING_encoder_command)+2);
	strcpy(g_conf.encoder_cmd,XING_encoder_command);
#elif DEFAULT_ENCODER==XING_BETA
	g_conf.encoder_cmd=malloc(strlen(XING_encoder_command)+2);
	strcpy(g_conf.encoder_cmd,XING_encoder_command);
#elif DEFAULT_ENCODER==LAME3
	g_conf.encoder_cmd=malloc(strlen(LAME3_encoder_command)+2);
	strcpy(g_conf.encoder_cmd,LAME3_encoder_command);
#elif DEFAULT_ENCODER==OLD_LAME3
	g_conf.encoder_cmd=malloc(strlen(LAME3_encoder_command)+2);
	strcpy(g_conf.encoder_cmd,LAME3_encoder_command);
#elif DEFAULT_ENCODER==LAME31x
	g_conf.encoder_cmd=malloc(strlen(LAME3_encoder_command)+2);
	strcpy(g_conf.encoder_cmd,LAME3_encoder_command);
#elif DEFAULT_ENCODER==GOGO
	g_conf.encoder_cmd=malloc(strlen(GOGO_encoder_command)+2);
	strcpy(g_conf.encoder_cmd,GOGO_encoder_command);
#else
	/* None of the other encoders work yet - Go and tell the authors! */
	g_conf.encoder_cmd=malloc(strlen(AJ_encoder_command)+2);
	strcpy(g_conf.encoder_cmd,AJ_encoder_command);
#endif
	g_conf.copyright=0;
	g_conf.debug=0;
	g_conf.rw_size=4096;
	g_conf.mixer=SOUNDCARD_MODE;
	g_conf.mix_control=0;
	g_conf.terminate_now=0;
	g_conf.random_seed=time(&now);
	/* setup stream zero for defaults */
	copy_defaults_to_stream(&(g_conf.e_str[0]));
}

void do_config_command(char *cmd,char *line,int *stream){
/* first do commands which set or unset flags with no options */
	
	if(!strcmp(cmd,"COPYRIGHT")) {
		g_conf.copyright=1;
	} else if(!strcmp(cmd,"NO_COPYRIGHT")){
		g_conf.copyright=0;
	} else if(!strcmp(cmd,"FULL_DUPLEX")){
		g_conf.full_duplex=1;
	} else if(!strcmp(cmd,"HALF_DUPLEX")){
		g_conf.full_duplex=0;
	} else if(!strcmp(cmd,"ICY_LOGIN")){
		g_conf.header_format=ICY_LOGIN;
	} else if(!strcmp(cmd,"X_AUDIOCAST_LOGIN")){
		g_conf.header_format=X_AUDIOCAST_LOGIN;
	} else if(!strcmp(cmd,"MIX_CONTROL_AUTO")) {
		g_conf.mix_control=2;
	} else if(!strcmp(cmd,"MIX_CONTROL_LOGGED")) {
		g_conf.mix_control=1;
	} else if(!strcmp(cmd,"MIX_CONTROL_MANUAL")) {
		g_conf.mix_control=0;	
	} else if(!strcmp(cmd,"MONO")) {
		g_conf.stereo=1;
	} else if(!strcmp(cmd,"STEREO")) {
		g_conf.stereo=2;
	} else if(!strcmp(cmd,"MIXER")) {
		g_conf.mixer=MP3MIXER_MODE;
	} else if(!strcmp(cmd,"NO_MIXER")) {
		g_conf.mixer=SOUNDCARD_MODE;
	} else if(!strcmp(cmd,"ESDMON")){
		g_conf.mixer=ESDMON_MODE;
	} else if(!strcmp(cmd,"SHOUT_MODE")){
	        g_conf.mixer=SHOUT_MODE;
	} else if(!strcmp(cmd,"SOUNDCARD")) {
		g_conf.soundcard=1;
	} else if(!strcmp(cmd,"NO_SOUNDCARD")) {
		g_conf.soundcard=0;
	}   

/* now all the commands which set numerical variables */
	else if(!strcmp(cmd,"BITRATE")) {
		sscanf(line,"%d",&(g_conf.bitrate));
	} else if(!strcmp(cmd,"DEBUG")) {
		sscanf(line,"%d",&(g_conf.debug));
	} else if(!strcmp(cmd,"DURATION")) {
		sscanf(line,"%ld",&(g_conf.end_time));
	} else if(!strcmp(cmd,"ENCODING_QUALITY")) {
		sscanf(line,"%d",&(g_conf.encoding_quality));
	} else if(!strcmp(cmd,"UPDATE_DELAY")) {
		sscanf(line,"%d",&(g_conf.meta_data));
	} else if(!strcmp(cmd,"PORT")) {
		sscanf(line,"%d",&(g_conf.port));
	} else if(!strcmp(cmd,"PUBLIC")) {
		sscanf(line,"%d",&(g_conf.icy_public));
	} else if(!strcmp(cmd,"SAMPLE_RATE")) {
		sscanf(line,"%d",&(g_conf.sample_rate));
	} else if(!strcmp(cmd,"VBR_QUALITY")) {
		sscanf(line,"%d",&(g_conf.vbr_quality));
	} else if(!strcmp(cmd,"VERBOSE")) {
		sscanf(line,"%d",&(g_conf.debug));
	}  
/* phew - now were' into those ones which copy strings */
	 else if(!strcmp(cmd,"CONTROL_FILE")) {
		 string_copy(&(g_conf.mix_control_file),line);
	 } else if(!strcmp(cmd,"DECODER_COMMAND")) {
		 string_copy(&(g_conf.decoder_cmd),line);
	 } else if(!strcmp(cmd,"DESCRIPTION")) {
		 string_copy(&(g_conf.description),line);
	 } else if(!strcmp(cmd,"ENCODER_ARGS")) {
	         string_copy(&(g_conf.encoder_args),line);
	 } else if(!strcmp(cmd,"GENRE")) {
		 string_copy(&(g_conf.icy_genre),line);
	 } else if(!strcmp(cmd,"MOUNTPOINT")) {
		 string_copy(&(g_conf.mountpoint),line);
	 } else if(!strcmp(cmd,"NAME")) {
		 string_copy(&(g_conf.icy_name),line);
	 } else if(!strcmp(cmd,"PASSWORD")) {
		 string_copy(&(g_conf.password),line);
	 } else if(!strcmp(cmd,"PLAYLIST")) {
		 string_copy(&(g_conf.playlist),line);
		 printf("%s\n", g_conf.playlist);
	 } else if(!strcmp(cmd,"REMOTE_DUMPFILE")) {
		 string_copy(&(g_conf.remote_dumpfile),line);
	 } else if(!strcmp(cmd,"SAVE_FILE")) {
		 string_copy(&(g_conf.recording_file),line);
	 } else if(!strcmp(cmd,"SERVER")) {
		 string_copy(&(g_conf.server),line);
	 } else if(!strcmp(cmd,"SOUND_DEVICE")) {
		 string_copy(&(g_conf.sound_input_file),line); 
	 } else if(!strcmp(cmd,"TRACK_LOGFILE")) {
		 string_copy(&(g_conf.track_logfile),line);
	 } else if(!strcmp(cmd,"LOGFILE_FORMAT")){
	         string_copy(&(g_conf.logfile_format),line);
	 } else if(!strcmp(cmd,"UPDATE_SCRIPT")){
	         string_copy(&(g_conf.update_script),line);	  
	 } else if(!strcmp(cmd,"URL")) {
		 string_copy(&(g_conf.icy_url),line);
	 } else if(!strcmp(cmd,"MIXER_CMD")) {
	 	string_copy(&g_conf.mixer_cmd,line);
		g_conf.mixer=COMMAND_MODE;
	 }
/* next there's the encoders - if you give them no string they use a default */
	else if(!strcmp(cmd,"USE_AJ_ENCODER")) {
		g_conf.encoder=AJ_ENCODER;
		if(line[0]!=0) string_copy(&(g_conf.encoder_cmd),line);
		else string_copy(&(g_conf.encoder_cmd),AJ_encoder_command);
	 } else if(!strcmp(cmd,"USE_LAME3")) {
		g_conf.encoder=LAME3;
		if(line[0]!=0) string_copy(&(g_conf.encoder_cmd),line);
		else string_copy(&(g_conf.encoder_cmd),LAME3_encoder_command);
	 } else if(!strcmp(cmd,"USE_OLD_LAME3")) {
		 g_conf.encoder=OLD_LAME3;
		 if(line[0]!=0) string_copy(&(g_conf.encoder_cmd),line);
		 else string_copy(&(g_conf.encoder_cmd),LAME3_encoder_command);
	 } else if(!strcmp(cmd,"USE_LAME31X")) {
		 g_conf.encoder=LAME31x;
		 if(line[0]!=0) string_copy(&(g_conf.encoder_cmd),line);
		 else string_copy(&(g_conf.encoder_cmd),LAME3_encoder_command);
	 } else if(!strcmp(cmd,"USE_L3ENC")) {
		g_conf.encoder=L3ENC;
		if(line[0]!=0) string_copy(&(g_conf.encoder_cmd),line);
		else string_copy(&(g_conf.encoder_cmd),L3ENC_encoder_command);
	 } else if(!strcmp(cmd,"USE_MP3ENC")) {
		g_conf.encoder=MP3ENC;
		if(line[0]!=0) string_copy(&(g_conf.encoder_cmd),line);
		else string_copy(&(g_conf.encoder_cmd),MP3ENC_encoder_command);
	 } else if(!strcmp(cmd,"USE_SCREAMER")) {
		g_conf.encoder=SCREAMER;
		if(line[0]!=0) string_copy(&(g_conf.encoder_cmd),line);
		else string_copy(&(g_conf.encoder_cmd),SCREAMER_encoder_command);
	 } else if(!strcmp(cmd,"USE_XING")) {
		g_conf.encoder=XING;
		if(line[0]!=0) string_copy(&(g_conf.encoder_cmd),line);
		else string_copy(&(g_conf.encoder_cmd),XING_encoder_command);
	 } else if(!strcmp(cmd,"USE_XING_VBR")) {
		g_conf.encoder=XING_VBR;
		if(line[0]!=0) string_copy(&(g_conf.encoder_cmd),line);
		else string_copy(&(g_conf.encoder_cmd),XING_encoder_command);
	 } else if(!strcmp(cmd,"USE_XING_BETA")) {
		g_conf.encoder=XING_VBR;
		if(line[0]!=0) string_copy(&(g_conf.encoder_cmd),line);
		else string_copy(&(g_conf.encoder_cmd),XING_encoder_command);
	 } else if(!strcmp(cmd,"USE_GOGO")) {
		g_conf.encoder=GOGO;
		if(line[0]!=0) string_copy(&(g_conf.encoder_cmd),line);
		else string_copy(&(g_conf.encoder_cmd),GOGO_encoder_command);
	 } 
/* finally the stream selection command */	
	else if(!strcmp(cmd,"ENCODER_STREAM_SET")) {
		copy_defaults_to_stream(&(g_conf.e_str[*stream]));
		in_stream_set=1;
		sscanf(line,"%d",stream);
		g_conf.recording_file=g_conf.e_str[*stream].recording_file;
		g_conf.remote_dumpfile=g_conf.e_str[*stream].remote_dumpfile;
		if(g_conf.e_str[*stream].enabled)
				copy_stream_to_defaults(&(g_conf.e_str[*stream]));
	} else {
		sprintf(line,"%s Configuration Option Not Understood",cmd);
		write_message(line,0);   
	} 
}


void read_config_file(char *file){
	FILE *in;
	char line[8192],cmd[8192];   /*So don't make any lines bigger....*/
	int i,enc_stream;
	
	if((in=fopen(file,"r"))==NULL){
		sprintf(line,"Could not open File %s",file);
		write_message(line,1);
		return;
	}
	enc_stream=0;
	g_conf.recording_file=g_conf.e_str[enc_stream].recording_file;
	copy_stream_to_defaults(&(g_conf.e_str[0]));
	while(!feof(in)){
		/* read fisrt CMD using scanf */
		fscanf(in,"%s",cmd);
		if(feof(in)) cmd[0]='#';
		/* then deal with the rest character at a time */
		i=0;
		line[0]=fgetc(in);
		/* strip off leading spaces */
		while(((line[0]==' ') || (line[0]=='\t'))&&(!feof(in))){
			line[0]=fgetc(in);
		}
		while((line[i]!='\n')&&(!feof(in))){
			i++;
			line[i]=fgetc(in);
		}
		line[i]=0;
		if(cmd[0]!='#'){
			/* make Everything Upper case */
			i=0;
			while(cmd[i]!=0) {
				cmd[i]=toupper(cmd[i]);
				i++;
			}
			do_config_command(cmd,line,&enc_stream);
		}
	}
	/* now copy the current settings to the current stream */
	copy_defaults_to_stream(&(g_conf.e_str[enc_stream]));
	fclose(in);
}

/* Fix up the final params and bomb out if anything stupid is set */
/* should catch any brain-dead configurations */
/* this is going to get real messy if I try to fix everything... */
void check_config(void){
	int speed;
	int i;
	int sample_max,chan_max;
	time_t now;
	
	/* look through the output channels and select the best rate for
	   the internal data */
	sample_max=default_sample_rate;
	chan_max=default_stereo;
	for(i=0;i<MAX_ENCODER_STREAMS;i++){
		if(g_conf.e_str[i].enabled){
			speed=get_legal_rate(g_conf.e_str[i].sample_rate);
			if(speed != g_conf.e_str[i].sample_rate){
				fprintf(stderr,"Using sample rate %d instead of %d on stream %d\n",speed,g_conf.e_str[i].sample_rate,i);
				g_conf.e_str[i].sample_rate=speed;
			}
			if(speed>sample_max)
				sample_max=speed;
			if(g_conf.e_str[i].stereo==2)
				g_conf.e_str[i].stereo = 1;
			else
				g_conf.e_str[i].stereo = 0;
			if(g_conf.e_str[i].stereo>chan_max)
				chan_max=g_conf.e_str[i].stereo;
			
			
			/* now check taht the parameters are OK */
			if(check_encoder_parameters(&(g_conf.e_str[i]))){
				fatal("Bad encoder parameters - check config");
			}
			/*
			  printf("%s\n",g_conf.e_str[i].server);
			  printf("%s\n",g_conf.e_str[i].password);
			  printf("%s\n",g_conf.e_str[i].mountpoint);
			  printf("%s\n",g_conf.e_str[i].name);
			  printf("%s\n",g_conf.e_str[i].genre);
			  printf("%s\n",g_conf.e_str[i].url);
			  printf("%d\n",g_conf.e_str[i].port);
			  printf("%s\n",g_conf.e_str[i].recording_file);
			  printf("%d\n",g_conf.e_str[i].sample_rate);
			  printf("%d\n",g_conf.e_str[i].bitrate);
			  printf("%d\n",g_conf.e_str[i].stereo);
			*/
			if((g_conf.e_str[i].remote_dumpfile!=NULL) && (g_conf.e_str[i].header_format==ICY_LOGIN)) {
				write_message("Warning, Stream %d has a remote dumpfile set, but uses icy headers.\n",0);
			}
		}
	}
	g_conf.sample_rate=sample_max;
	g_conf.stereo=chan_max;
		
        /* check we're not being silly buggers with the sound */
#ifndef SOUNDCARD_SUPPORT
	g_conf.soundcard=0;
#endif
	/* if you choose simple mode and switch of the soundcard then 
	   you won't get anything - Eeejit! */
	if((!g_conf.mixer)&&(!g_conf.soundcard))
		fatal("Line In mode *and* no soundcard??????? Eeejit!");

	/* if something has set the end_time variable then the system needs to
	   know when to quit */
	if(g_conf.end_time){
		if(g_conf.end_time < 0)
			fatal("What kind of person stops before they starts?\nDURATION set to a negative value");
		time(&now);
		g_conf.end_time+=now;
	}
}

void print_usage(char *name){
printf("LiveIce: Live mp3 streamer\n");
printf("Usage  %s <options>\n",name);
printf("    supported command line options\n");
printf("    -h                 print this help screen\n");
printf("    -s <servername>    remote server\n");
printf("    -n <name>          stream name\n");
printf("    -g <genre>         stream genre\n");
printf("    -x                 make stream private\n");
printf("    -P <password>      login password\n");
printf("    -u <url>           stream url\n");
printf("    -o <port>          target port number\n");
printf("    -b <bitrate>       stream bitrate\n");
printf("    -B <quality>       VBR quality factor (vbr streams only)\n");
printf("    -r <sample rate>   audio sampling rate\n");
printf("    -c <channels>      no. of audio channel (mono/stereo)\n");
printf("    -C                 set copyright flag on stream\n");
printf("    -f <flag>          disable/enable experimental full-duplex mode\n");
printf("    -V <level>         debug/verbose level\n");
printf("    -T <seconds>       timeout, terminate after a certain time period\n");
printf("    -M                 Mp3Mixer mode\n");
printf("    -m                 Simple, Line-in mode\n");
printf("    -e                 esdmon mode\n");
printf("    -F <file>          read another configuration file\n");
printf("    -k <mode>          mixer control mode\n");
printf("    -K <logfile>       mixer control logfile\n");
printf("    -@ <frontend type> 0=curses 1=external program 2=none\n");
printf("\nMore options are settable withing the liveice.cfg and /etc/liveice.cfg files\n");
}


void do_config(int argc, char *argv[])
{
	int i,enc_stream;
	char *configfile;
	default_config();

	configfile = malloc(strlen(ETCDIR) + strlen("liveice.cfg") + 5);
	configfile = strcpy(configfile, ETCDIR);
	configfile = strcat(configfile, "/liveice.cfg");
	read_config_file(configfile);
	free(configfile);

	read_config_file("liveice.cfg");

	enc_stream=0;
	g_conf.recording_file=g_conf.e_str[enc_stream].recording_file;
	copy_stream_to_defaults(&(g_conf.e_str[0]));
	for(i=1;i<argc;i++){
		if(argv[i][0]=='-'){
			switch(argv[i][1]){
			case 'h':
				print_usage(argv[0]);
				exit(0);
				break;
			case 's':
				i++;
				g_conf.server=argv[i];
				break;
			case 'n':
			        i++;
			        g_conf.icy_name=argv[i];
			        break;
			case 'g':
			        i++;
				g_conf.icy_genre=argv[i];
				break;
			case 'x':
			        g_conf.icy_public=0;
				break;
			case 'P':
                                i++;
			        g_conf.password=argv[i];
				break;
		        case 'u':
			        i++;
				g_conf.icy_url=argv[i];
				break;
			case 'o':
				i++;
				g_conf.port=atoi(argv[i]);
				break;
			case 'b':
			        i++;
				g_conf.bitrate=atoi(argv[i]);
				break;
			case 'B':
				i++;
				g_conf.vbr_quality=atoi(argv[i]);
				break;
			case 'r':
				i++;
				g_conf.sample_rate=atoi(argv[i]);
				break;
			case 'c':
			        i++;
				g_conf.stereo=atoi(argv[i]);
				break;
			case 'C':
				g_conf.copyright=1;
				break;
		        case 'f':
				i++;
			        g_conf.full_duplex=atoi(argv[i]);
				break;
			case 'V':
			        g_conf.debug=1;
 				break;
			case 'w':
			        i++;
			        g_conf.rw_size=atoi(argv[i]);
				break;
			case 'T':
				i++;
				g_conf.end_time=atoi(argv[i]);
				break;
			case 'M':
			        g_conf.mixer=MP3MIXER_MODE;
				break;
			case 'm':
			        g_conf.mixer=SOUNDCARD_MODE;
				break;
			case 'E':
				g_conf.mixer=ESDMON_MODE;
				break;
			case 'F':
			        i++;
			        read_config_file(argv[i]);
				break;
			case 'k':
				i++;
				g_conf.mix_control=atoi(argv[i]);
				break;
			case 'K':
				i++;
				g_conf.mix_control_file=argv[i];
				break;    				
			case '@':
				i++;
				g_conf.frontend=atoi(argv[i]);
				break;
			default:
				write_message("Unrecognised command line switch",0);
				exit(0);
				break;
			} 
		} else {
		  write_message("Unrecognised Command Line option",0);
		  exit(0);
		}
	}

	/* now copy the data into the current stream */
	copy_defaults_to_stream(&(g_conf.e_str[enc_stream]));
	check_config();
}
