/************************************************************************
 *   psybnc2.2.2, src/p_inifunc.c
 *   Copyright (C) 2001 the most psychoid  and
 *                      the cool lam3rz IRC Group, IRCnet
 *			http://www.psychoid.lam3rz.de
 *
 *   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 1, 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.
 */

#ifndef lint
static char rcsid[] = "@(#)$Id: p_inifunc.c, v 2.2.2 2001/03/25 02:02:02 psychoid Exp $";
#endif

#define P_INIFUNC

#include <p_global.h>

/* reset the config cache */

int resetconfig()
{
    struct stringarray *wconf,*owconf;
    pcontext;
    wconf=conf;
    while(wconf!=NULL)
    {
	if (wconf->entry!=NULL)
	    free(wconf->entry);
	owconf=wconf;
	wconf=wconf->next;
	free(owconf);
    }
    conf=NULL;
    return 0x0;
}

/* read the config file */

int readconfig()
{
    FILE *handle;
    struct stringarray *wconf;
    char inistring[400];
    char *pt;
    pcontext;
    wconf=conf;
    if(conf!=NULL) resetconfig();
    handle=fopen(configfile,"r");
    if(handle==NULL) return -1;
    while(fgets(inistring,sizeof(inistring),handle))
    {
	pt=strchr(inistring,'\n');
	if(pt!=NULL) *pt=0;
	if(wconf==NULL)
	{
	    wconf=(struct stringarray *)pmalloc(sizeof(struct stringarray));
	    conf=wconf;
	} else {
	    wconf->next=(struct stringarray *)pmalloc(sizeof(struct stringarray));
	    wconf=wconf->next;
	}
	wconf->entry=(char *)pmalloc(strlen(inistring)+1);
	strcpy(wconf->entry,inistring);
    }
    fclose(handle);
    return 0x0;
}

/* write the config file */

int flushconfig()
{
    FILE *handle;
    struct stringarray *wconf;
    pcontext;
    oldfile(configfile);
    handle=fopen(configfile,"w");
    wconf=conf;
    while(wconf)
    {
	if(wconf->entry!=NULL) { 
	   if(strlen(wconf->entry)>1)
	       fprintf(handle,"%s\n",wconf->entry);
	}
	wconf=wconf->next;
    }
    fclose(handle);
    return 0x0;
}

/* erases a section from the config */

int clearsectionconfig(char *pattern)
{
    struct stringarray *wconf,*xconf;
    pcontext;
    wconf=conf;
    xconf=conf;
    while(wconf)
    {
	if(wconf->entry!=NULL)
	{
	    if(strstr(wconf->entry,pattern)==wconf->entry)
	    {
		if(wconf==conf)
		{
		    conf=wconf->next;
		    xconf=conf;
		} else {
		    xconf->next=wconf->next;
		}
    		free(wconf->entry);
		free(wconf);
		wconf=xconf;
	    }
	}
	xconf=wconf;
	wconf=wconf->next;
    }
}

/* get entry from conf-file */

int getini(char *section, char *param,char *inidat)
{
   char ppuf[400];
   struct stringarray *wconf;
   char *po;
   pcontext;
   wconf=conf;
   memset(value,0x0,sizeof(value));    
   ap_snprintf(ppuf,sizeof(ppuf),"%s.%s.%s=",inidat,section,param);
   while (wconf!=NULL) 
   {
	if(wconf->entry!=NULL)
	{
	    po = strstr(wconf->entry,ppuf);
	    if (po == wconf->entry) {
 		po = po + strlen(ppuf);
		strmncpy(value,po,sizeof(value));
		return 0x0; /* found, returning */
	    }
	}
	wconf=wconf->next;
   }
   /* not found */
   return -2;
}

/* write entry to configcache or delete if if data = NULL */

int writeini(char *section, char *param, char *inidat, char *data)
{
    char ppuf[200];
    char spuf[200];
    char buf[2048];
    char tx[20];
    char *po;
    int wasinsection;
    char *data_p;
    struct stringarray *wconf,*xconf,*sectconf;
    wconf=conf;
    pcontext;
    data_p = data;
    if (data_p != NULL)
       if (strlen(data) == 0) data_p = NULL;
    wasinsection = 0;
    ap_snprintf(ppuf,sizeof(ppuf),"%s.%s.%s=",inidat,section,param);
    ap_snprintf(spuf,sizeof(spuf),"%s.%s.",inidat,section);
    if(data_p!=NULL)
	ap_snprintf(buf,sizeof(buf),"%s%s",ppuf,data_p);
    xconf=conf;
    sectconf=conf;
    while (wconf) 
    {
      if(wconf->entry!=NULL)
      {
    	   po = strstr(wconf->entry,spuf);
           if (po == wconf->entry) 
	   {
	      sectconf=xconf; /* save last entry of section */
	      wasinsection = 1; /* we had been in the section */
	      po = strstr(wconf->entry,ppuf);
	      if (po == wconf->entry) {
		 if(data_p==NULL)
		 {
		    if(wconf==conf)
		    {
			conf=wconf->next;
			xconf=conf;
		    } else {
			xconf->next=wconf->next;
		    }		     
		    free(wconf->entry);
		    free(wconf);
		    wconf=xconf;
		    return 0x0;
		 } else {
		    free(wconf->entry);
		    wconf->entry=(char *)pmalloc(strlen(buf)+2);
		    strmncpy(wconf->entry,buf,strlen(buf)+1);
		    return 0x0;
		 }    
	      }
	   }
      }
      xconf=wconf;
      wconf=wconf->next;
    }
    if(data_p==NULL) return 0x0;
    if(wasinsection==0) 
    {
	xconf->next=(struct stringarray *)pmalloc(sizeof(struct stringarray));
	xconf=xconf->next;
    } else {
	xconf=sectconf;
	wconf=(struct stringarray *)pmalloc(sizeof(struct stringarray));
	wconf->next=xconf->next;
	xconf->next=wconf;
	xconf=wconf;
    }
    xconf->entry=(char *)pmalloc(strlen(buf)+2);
    strmncpy(xconf->entry,buf,strlen(buf)+1);
    return 0x0;
}

int lastfree;

int countconfentries(char *section, char *entry, char *fname)
{
    int cnt=0;
    char buf[200];
    int i,rc;
    lastfree=999;
    for (i=0;i<500;i++)
    {
	if(strchr(section,'%')!=NULL)
	{
	    ap_snprintf(buf,sizeof(buf),section,i);	
	    rc=getini(buf,entry,fname);
	} else
	if(strchr(entry,'%')!=NULL)
	{
	    ap_snprintf(buf,sizeof(buf),entry,i);	
	    rc=getini(section,buf,fname);
	} else
	if(strchr(fname,'%')!=NULL)
	{
	    ap_snprintf(buf,sizeof(buf),fname,i);	
	    rc=getini(section,entry,buf);
	}
	if(rc==0) 
	    cnt++; 
	else 
	    if(lastfree>i) lastfree=i;
    }
    return cnt;
}



/* get server from ini by number */

int getserver(int srvnr, int usernum)
{
   char fnmuser[20];
   char buf[100];
   int ern;
   ap_snprintf(fnmuser,sizeof(fnmuser),"USER%d",usernum);
   ap_snprintf(buf,sizeof(buf),"SERVER%d",srvnr);
   ern = getini("SERVERS",buf,fnmuser);
   if (ern != 0) { return ern; }
   ap_snprintf(user(usernum)->server,sizeof(user(usernum)->server),"%s",value);
   ap_snprintf(buf,sizeof(buf),"PORT%d",srvnr);
   ern = getini("SERVERS",buf,fnmuser);
   if (ern != 0) { user(usernum)->port = 6667; } else { user(usernum)->port = atoi(value); }
   ap_snprintf(buf,sizeof(buf),"SPASS%d",srvnr);
   ern = getini("SERVERS",buf,fnmuser);
   if (ern != 0) { *user(usernum)->spass=0; return 0; }
   ap_snprintf(user(usernum)->spass,sizeof(user(usernum)->spass),"%s",value);
   return 0;
}

/* get next server */

int getnextserver(int nuser)
{
    int first;
   pcontext;
    first = user(nuser)->currentserver;
    while(1)
    {
	user(nuser)->currentserver++;
	if (getserver(user(nuser)->currentserver,nuser) ==0)
	{
	    return 0; /* found it, bye */
	}
	if (user(nuser)->currentserver>20) user(nuser)->currentserver = 0;
	if (user(nuser)->currentserver == first) return -1;
    }
    return 1;
}

/* delete user files */
int deluser(int uind)
{
    char buf[60];
    pcontext;
    ap_snprintf(buf,sizeof(buf),"log/USER%d.LOG",uind);
    oldfile(buf);
    ap_snprintf(buf,sizeof(buf),"log/USER%d.TRA",uind);
    oldfile(buf);
    ap_snprintf(buf,sizeof(buf),"USER%d.",uind);
    clearsectionconfig(buf);
    flushconfig();
}
