/*
   This file is part of the IRC Bounce source code
   copyright (c) 1998 v00d00 Net Services
   and is distributed according to the GNU general public license.

   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., 675 Mass Ave, Cambridge, MA 02139, USA.

   The author (Robert Clark) can be reached at: v00d00@hempseed.com

   This code is based on Irc Proxy (c)1997-98 James Seter
*/

#include "common.h"

struct vhost *addvhost(struct vhost *list_ptr)
{
   while (list_ptr->next!=NULL) list_ptr=list_ptr->next;
   list_ptr->next=(struct vhost *) malloc (sizeof (struct vhost));
   if (list_ptr->next!=NULL) (list_ptr->next)->next=(struct vhost *) NULL;
   return (list_ptr->next);
}

int
loadconf(tconf *conf)
{
   FILE *f;
   char *confcmd,*confval,line[100];
   int howfar;

   if ((f=fopen(conf->cfgfile,"r"))==NULL) return 0;
   howfar=0;
   while(!feof(f)) {
      memset(line,0,sizeof(line));
      fgets(line,sizeof(line),f);
      howfar++;
      if (!strlen(line)) continue;
      if (strncmp(line,"#",1)) {
         confcmd=NULL;
         confval=NULL;
         confcmd=strtok(line,":");
         if (!confcmd) continue;
         confval=strtok(NULL,"\n");
         if (!confval) continue;
         if (!option(conf,confcmd,confval))
            printf("Config line %i rejected (invalid command '%s')\n",howfar,confcmd);
      }
   }
   fclose(f);
}

int
option(tconf *conf, char *cmd, char *val)
{
   struct vhost *tmpvhst;

   if (!strcasecmp(cmd,"p")||!strcasecmp(cmd,"pt"))
      conf->lport=atoi(val);
   else if (!strcasecmp(cmd,"m")||!strcasecmp(cmd,"mu"))
      conf->maxusers=atoi(val);
   else if (!strcasecmp(cmd,"d")||!strcasecmp(cmd,"dp"))
      conf->dport=atoi(val);
   else if (!strcasecmp(cmd,"h")||!strcasecmp(cmd,"lh"))
      strncpy(conf->lhost,val,sizeof(conf->lhost));
   else if (!strcasecmp(cmd,"l")||!strcasecmp(cmd,"lf"))
      strncpy(conf->logfile,val,sizeof(conf->logfile));
   else if (!strcasecmp(cmd,"z")||!strcasecmp(cmd,"pf"))
      strncpy(conf->pidfile,val,sizeof(conf->pidfile));
   else if (!strcasecmp(cmd,"a")||!strcasecmp(cmd,"ps"))
      strncpy(conf->pass,val,sizeof(conf->pass));
   else if (!strcasecmp(cmd,"f")||!strcasecmp(cmd,"id"))
      strncpy(conf->fakeid,val,sizeof(conf->fakeid));
   else if (!strcasecmp(cmd,"c")||!strcasecmp(cmd,"cl"))
      strncpy(conf->cloak,val,sizeof(conf->cloak));
   else if (!strcasecmp(cmd,"o"))
      strncpy(conf->oper,val,sizeof(conf->oper));
   else if (!strcasecmp(cmd,"v")||!strcasecmp(cmd,"vh")) {
      if(conf->vhosts.host[0] == 0) {
         strncpy(conf->vhosts.host,val,HOSTLEN);
      } else {
         tmpvhst=addvhost(&conf->vhosts);
         if(tmpvhst == NULL) {
            putlog("Ram Error!");
            exit(-1);
         }
         strncpy(tmpvhst->host,val,HOSTLEN);
      }
   } else return 0;
}

#define SYNTAX "%s\t%s\n"

void
saveconf(tconf *conf)
{
   FILE *f;
   struct vhost *vhosts;

   void savestr(char *item, char *s, char *s2, int i)
   { fprintf(f,"%s%s:%s\n",((((i==1)&&(!strcmp(s,s2)))||(!(*s))) ? "#" : ""),item,(*s ? s : s2)); }

   void saveint(char *item, int i, int i2)
   { fprintf(f,"%s%s:%u\n",(i==i2 ? "#" : ""),item,i); }

   if ((f=fopen(conf->cfgfile,"w"))==NULL) return;
   fprintf(f,"#Configuration file for iBNC %s\n\n",VERSION);
   fprintf(f,SYNTAX,"#Option","Description");
   fprintf(f,SYNTAX,"#------","-----------");
   fprintf(f,SYNTAX,"# H:","virtual vhost to use for incoming connections");
   fprintf(f,SYNTAX,"# P:","port to use for incoming connections");
   fprintf(f,SYNTAX,"# V:","virtual host(s) to use for outgoing connections");
   fprintf(f,SYNTAX,"#","(one vhost per V:)");
   fprintf(f,SYNTAX,"# D:","default port to use for outgoing connections");
   fprintf(f,SYNTAX,"# M:","maximum connections you'll allow (0 = unlimited)");
   fprintf(f,SYNTAX,"# A:","auth password for incoming connections");
   fprintf(f,SYNTAX,"# O:","oper password to enable OPER, WHO and KILL");
   fprintf(f,SYNTAX,"# C:","cloak the program name to show in a \"ps\" listing");
   fprintf(f,SYNTAX,"# F:","specify the ident spoof file to write to (eg. .noident, .fakeid)");
   fprintf(f,SYNTAX,"# L:","specify an alternate log file (default: bnc.log)");
   fprintf(f,SYNTAX,"# Z:","specify an alternate pid file (default: bnc.pid)\n");

   savestr("H",conf->lhost,"my.local.host.org",0);
   saveint("P",conf->lport,6667);

   if (*conf->vhosts.host) {
      vhosts=&conf->vhosts;
      while (vhosts!=NULL) {
         fprintf(f,"V:%s\n",vhosts->host);
         vhosts=vhosts->next;
      }
   } else fprintf(f,"#V:my.virtual.host.org\n");
   saveint("D",conf->dport,6667);
   saveint("M",conf->maxusers,100);
   savestr("A",conf->pass,"limit20chars",0);
   savestr("O",conf->oper,"limit20chars",0);
   savestr("C",conf->cloak,"emacs",0);
   savestr("F",conf->fakeid,".noident",0);
   savestr("L",conf->logfile,"bnc.log",1);
   savestr("Z",conf->pidfile,"bnc.pid",1);
   fclose(f);
}
