#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include <proto/dos.h>

#include "rn.h"

extern char Newshome[];
extern char Newsgroupfile[];

char *articlename(char *file,char *groupname,int number,int flag)
{
	register int i,j;
	register char ch;

	if(!flag)
		strcpy(file,Newshome);
	else
		file[0]='\0';

	i=strlen(file);
	j=0;
	while(ch=groupname[j++])
	{
		file[i++]=(ch=='.')?'/':ch;
	}
	file[i]='/';
	sprintf(file+i+1,"%d",number);

	return file;
}


char *articlegroup(char *file,char *groupname)
{	register int i,j;
	register char ch;

	strcpy(file,Newshome);
	i=strlen(file);
	j=0;
	while(ch=groupname[j++])
	{
		file[i++]=(ch=='.')?'/':ch;
	}
	file[i]='\0';

	return file;
}


int is_group(char *groupname)
{	char dir[100];
	BPTR lock;

	articlegroup(dir,groupname);
	if(lock=Lock(dir,ACCESS_READ))
	{
		UnLock(lock);
		return -1;
	}
	else
		return 0;
}


long get_next(char *groupname)
{	char file[120];
	FILE *fp;
	long i=0;

	articlegroup(file,groupname);
	strcat(file,"/.next");
	if(fp=fopen(file,"rb"))
	{
		fgets(file,40,fp);
		fclose(fp);
		i=atol(file);
	}
	return i;
}


long get_lowest(char *groupname,int highest)
{	char file[256];
	FILE *fp;
	BPTR lock;
	long i;

	articlegroup(file,groupname);
	strcat(file,"/.lowest");
	if(fp=fopen(file,"rb"))
	{
		fgets(file,40,fp);
		fclose(fp);
		i=atol(file);

		if(i==highest)
			return i;

		if(i<highest)
		{
			articlegroup(file,groupname);
			sprintf(file+strlen(file),"/%ld",i);
			if(lock=Lock(file,ACCESS_READ))
			{
				UnLock(lock);
				return i;
			}
		}
	}
	printf("Checking %s\n",groupname);
	i=findlowest(groupname,highest,0);
	if(i>highest)
		i=highest;
	set_lowest(groupname,i);
	return i;
}


int  set_next(char *groupname,long next)
{	char file[120];
	FILE *fp;

	articlegroup(file,groupname);
	strcat(file,"/.next");
	if(fp=fopen(file,"wb"))
	{
		fprintf(fp,"%ld\n",next);
		fclose(fp);
		return 0;
	}
	else
		return -1;
}

long inc_next(char *groupname)
{	char file[120],temp[20];
	FILE *fp;
	long i=0;

	articlegroup(file,groupname);
	strcat(file,"/.next");
	if(fp=fopen(file,"rb"))
	{
		fgets(temp,15,fp);
		fclose(fp);
		i=atol(temp);
	}
	if(fp=fopen(file,"wb"))
	{
		fprintf(fp,"%ld\n",i+1);
		fclose(fp);
		return i;
	}
	else
		return 0;
}


int  set_lowest(char *groupname,long lowest)
{	char file[120];
	FILE *fp;

	articlegroup(file,groupname);
	strcat(file,"/.lowest");
	if(fp=fopen(file,"wb"))
	{
		fprintf(fp,"%ld\n",lowest);
		fclose(fp);
		return 0;
	}
	else
		return -1;
}


int findlowest(char *groupname,int highest,int oldlowest)
{	char temp[256];
	int pos=highest-oldlowest+2,cur,delta=1;
	BPTR lock;

	while(delta<pos)
		delta<<=1;

	cur=highest-delta+1;

	articlegroup(temp,groupname);
	pos=strlen(temp);
	while(delta)
	{
		sprintf(temp+pos,"/%ld",cur);
		if(cur>0 && (lock=Lock(temp,ACCESS_READ)))
		{
			UnLock(lock);
			if(delta==1)
			{
				return cur;
			}
			else
			{
				delta/=2;
				cur-=delta;
			}
		}
		else
		{
			delta/=2;
			cur+=delta;
		}
	}
	return cur+1;
}

void update_active(char *filename)
{	int i,j;
	FILE *fp,*fp2;
	char temp[100],groupname[80];

	if(fp2=fopen(filename,"wb"))
	{
		if(fp=fopen(Newsgroupfile,"rb"))
		{
			while(!feof(fp))
			{
				if(fgets(temp,80,fp)==0)
					break;
				i=strlen(temp)-1;
				if(i<0 || feof(fp))
					break;

				if(!i)
					continue;

				temp[i]=0;
				i=0;
				while(temp[i] && temp[i]!=' ' && temp[i]!='\t')
					i++;

				strncpy(groupname,temp,i);
				groupname[i]=0;

				i=get_next(groupname)-1;
				if(i<0)
				{
					i=0;
				}
				j=get_lowest(groupname,i);
				if(i<j)
					i=j;
				fprintf(fp2,"%s %07d %07d y\n",groupname,i,j);
			}
			fclose(fp);
		}
		fclose(fp2);
	}
}


int add_group(char *groupname,ULONG expire,ULONG flags)
{	register int i,j;
	char nimi[160];
	register char ch;
	FILE *fp;
	long lock;

	strcpy(nimi,Newshome);
	i=strlen(nimi);
	j=0;
	while(ch=groupname[j])
	{
		if(ch=='.')
		{
			nimi[i]=0;
			mkdir(nimi);
			nimi[i]='/';
		}
		else
			nimi[i]=ch;
		++i;
		++j;
	}
	nimi[i]=0;
	if(lock=Lock(nimi,ACCESS_READ))
	{
		UnLock(lock);
	}
	else
	{
		if(mkdir(nimi))
		{
			return -1;
		}
	}

	set_next(groupname,get_next(groupname));
	set_lowest(groupname,0);

/* add to newsgroups-file */

	if((fp=fopen(Newsgroupfile,"ab")) || (fp=fopen(Newsgroupfile,"wb")))
	{
		fprintf(fp,"%s %ld ",groupname,expire);
		if(flags & FLAG_MODERATED)
			fputc('m',fp);
		if(flags & FLAG_READ_ONLY)
			fputc('r',fp);
		fputc('\n',fp);
		fclose(fp);
		return 0;
	}
	return -1;
}

int delete_group(char *groupname)
{	FILE *fp1,*fp2;
	char nimi[120];
	int len=strlen(groupname);

	sprintf(nimi,"%s.new",Newsgroupfile);
	if(fp2=fopen(nimi,"wb"))
	{
		if(fp1=fopen(Newsgroupfile,"rb"))
		{
			while(!feof(fp1))
			{
				if(fgets(nimi,120,fp1)==0)
					break;
				if((nimi[len]!=' ' && nimi[len]!='\t') || strncmp(nimi,groupname,len))
					fputs(nimi,fp2);
			}
			fclose(fp1);
		}
		fclose(fp2);
	}
	sprintf(nimi,"%s.new",Newsgroupfile);
	DeleteFile(Newsgroupfile);
	Rename(nimi,Newsgroupfile);

	return 0;
}
