/**********************************************************************
 
	Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
	This program is free software; you can redistribute it 
	and/or modify it under the terms of the GLOBALBASE 
	Library General Public License (G-LGPL) as published by 

	http://www.globalbase.org/
 
	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.

**********************************************************************/



#include	<stdlib.h>
#include	<netdb.h>
#include	<errno.h>
#include	<sys/types.h>
#include        <sys/socket.h>
#include	"memory_debug.h"
#include	"task.h"
#include	"utils.h"
#include	"server.h"


extern SEM netutils_lock;

void
init_access_permission(ACCESS_PERMISSION * ap)
{
	ap->head = ap->tail = 0;
}

void
free_access_list(ACCESS_PERMISSION * ap)
{
ACCESS_LIST * al;
	for ( ; ap->head ; ) {
		al = ap->head;
		ap->head = al->next;

		if ( al->domain )
			d_f_ree(al->domain);
		d_f_ree(al);
	}
}

void
insert_access_list(
	ACCESS_PERMISSION * ap,
	int	ip,
	int	mask,
	char *	domain,
	int	type)
{
ACCESS_LIST * al;
	al = d_alloc(sizeof(*al),183);
	al->ip = ip;
	al->mask = mask;
	if ( ip )
		al->domain = 0;
	else if ( domain == 0 ) {
		al->ip = 0;
		al->mask = 0;
		al->domain = 0;
	}
	else {
		al->domain = copy_str(domain);
change_memtype(al->domain,1020);
	}
	al->type = type;

	al->next = 0;
	if ( ap->head ) {
		ap->tail->next = al;
		ap->tail = al;
	}
	else {
		ap->head = ap->tail = al;
	}
}

extern int accept_test;

int
check_permission(ACCESS_PERMISSION * ap,int ip)
{
HOST_ENTRY * hp;
char ** q;
ACCESS_LIST * al;
int len1,len2;
int ip_addr;
int retry_cnt;

accept_test = 121;
	ip_addr = ip;
accept_test = 122;
	hp = r_gethostbyaddr(getHA_v4(ip_addr));
accept_test = 123;
	
	for ( al = ap->head ; al ; al = al->next ) {
accept_test = 124;
		if ( al->ip ) {
			if ( (ip&al->mask) == al->ip ) {
accept_test = 130;
				return al->type;
			}
			continue;
		}
		if ( al->domain == 0 ) {
accept_test = 129;
			return al->type;
		}
		if ( hp == 0 )
			continue;
accept_test = 125;
		len1 = strlen(al->domain);
		q = hp->names;
		for ( ; *q ; q ++ ) {
			len2 = strlen(*q);
			if ( len2 < len1 )
				continue;
			if ( strcmp(&(*q)[len2-len1],al->domain)
					== 0 ) {
				if ( len2 == len1 ) {
					return al->type;
				}
				if ( (*q)[len2-len1-1] == '.' ) {
accept_test = 128;
					return al->type;
				}
			}
		}
accept_test = 126;
	}
accept_test = 127;
	return AP_DENY;
}


