/*
** ypserver.c			YP server routines.
**
** Copyright (c) 1993 Signum Support AB, Sweden
**
** This file is part of the NYS YP Server.
**
** The NYS YP Server 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.
**
** The NYS YP Server 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 the NYS YP Server; see the file COPYING.  If
** not, write to the Free Software Foundation, Inc., 675 Mass Ave,
** Cambridge, MA 02139, USA.
**
** Author: Peter Eriksson <pen@signum.se>
*/

#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <ndbm.h>
#include "yp.h"


#define _PATH_YP   "/var/yp"
char *path_ypdb = _PATH_YP;

int debug_flag = 1;

void *ypproc_null_2_svc(void *dummy, struct svc_req *rqstp)
{
    static int foo;

    return (void *) &foo;
}

int is_valid_domain(char *name)
{
    char buf[1025];
    struct stat sbuf;
    
    
    sprintf(buf, "%s/%s", path_ypdb, name);
    if (stat(buf, &sbuf) < 0 || !S_ISDIR(sbuf.st_mode))
	return 0;

    return 1;
}

bool_t *ypproc_domain_2_svc(domainname *name, struct svc_req *rqstp)
{
    static bool_t result;
    
    if (is_valid_domain(name))
	result = TRUE;
    else
	result = FALSE;
    
    return &result;
}

bool_t *ypproc_domain_nonack_2_svc(domainname *name, struct svc_req *rqstp)
{
    static bool_t result;

    if (!is_valid_domain(name))
	return NULL;
    
    result = TRUE;
    return &result;
}


DBM *open_database(char *domain, char *map)
{
    DBM *dbp;
    char buf[1025];

    sprintf(buf, "%s/%s/%s", path_ypdb, domain, map);
    
    dbp = dbm_open(buf, O_RDONLY, 0700);

    if (debug_flag && dbp == NULL)
	fprintf(stderr, "*** Failed domain=%s, map=%s\n", domain, map);
    
    return dbp;
}


ypresp_val *ypproc_match_2_svc(ypreq_key *key, struct svc_req *rqstp)
{
    static ypresp_val result;

    if (debug_flag)
    {
	fprintf(stderr, "ypproc_match():\n");
	fprintf(stderr, "\tdomainname = \"%s\"\n", key->domain);
	fprintf(stderr, "\tmapname = \"%s\"\n", key->map);
	fprintf(stderr, "\tkeydat = \"%.*s\"\n", key->key.keydat_len,
		key->key.keydat_val);
    }

    result.val.valdat_len = 0;
    result.val.valdat_val = NULL;
    
    if (!is_valid_domain(key->domain))
	result.stat = YP_NODOM;
    else
    {
	datum rdat, qdat;
	
	DBM *dbp = open_database(key->domain, key->map);
	if (dbp == NULL)
	    result.stat = YP_NOMAP;
	else
	{
	    qdat.dsize = key->key.keydat_len;
	    qdat.dptr = key->key.keydat_val;

	    rdat = dbm_fetch(dbp, qdat);
	    if (rdat.dptr == NULL)
		result.stat = YP_NOKEY;
	    else
	    {
		result.stat = YP_TRUE;
		result.val.valdat_len = rdat.dsize;
		result.val.valdat_val = rdat.dptr;
	    }
	}
    }
	
    return &result;
}

ypresp_key_val *ypproc_first_2_svc(ypreq_key *key, struct svc_req *rqstp)
{
    static ypresp_key_val result;


    if (debug_flag)
    {
	fprintf(stderr, "ypproc_match():\n");
	fprintf(stderr, "\tdomainname = \"%s\"\n", key->domain);
	fprintf(stderr, "\tmapname = \"%s\"\n", key->map);
	fprintf(stderr, "\tkeydat = \"%.*s\"\n", key->key.keydat_len,
		key->key.keydat_val);
    }

    if (!is_valid_domain(key->domain))
	result.stat = YP_NODOM;
    else
	result.stat = YP_BADDB;

    result.key.keydat_len = 0;
    result.key.keydat_val = NULL;
    result.val.valdat_len = 0;
    result.val.valdat_val = NULL;
    
    return &result;
}

ypresp_key_val *ypproc_next_2_svc(ypreq_key *key, struct svc_req *rqstp)
{
    static ypresp_key_val result;


    if (debug_flag)
    {
	fprintf(stderr, "ypproc_match():\n");
	fprintf(stderr, "\tdomainname = \"%s\"\n", key->domain);
	fprintf(stderr, "\tmapname = \"%s\"\n", key->map);
	fprintf(stderr, "\tkeydat = \"%.*s\"\n", key->key.keydat_len,
		key->key.keydat_val);
    }


    if (!is_valid_domain(key->domain))
	result.stat = YP_NODOM;
    else
	result.stat = YP_BADDB;

    result.key.keydat_len = 0;
    result.key.keydat_val = NULL;
    result.val.valdat_len = 0;
    result.val.valdat_val = NULL;
    
    return &result;
}

print_ypmap_parms(struct ypmap_parms *pp)
{
    fprintf(stderr, "\t\tdomain   = \"%s\"\n", pp->domain);
    fprintf(stderr, "\t\tmap      = \"%s\"\n", pp->map);
    fprintf(stderr, "\t\tordernum = %u\n", pp->ordernum);
    fprintf(stderr, "\t\tpeer     = \"%s\"\n", pp->peer);
}

ypresp_xfr *ypproc_xfr_2_svc(ypreq_xfr *xfr, struct svc_req *rqstp)
{
    static ypresp_xfr result;

    if (debug_flag)
    {
	fprintf(stderr, "ypproc_xfr_2_svc():\n\tmap_parms:\n");
	print_ypmap_parms(&xfr->map_parms);
	fprintf(stderr, "\ttransid = %u\n", xfr->transid);
	fprintf(stderr, "\tprog = %u\n", xfr->prog);
	fprintf(stderr, "\tport = %u\n", xfr->port);
    }

    result.transid = xfr->transid;
    result.xfrstat = YPXFR_REFUSED;
    
    return &result;
}

void *ypproc_clear_2_svc(void *dummy, struct svc_req *rqstp)
{
    static int foo;

    return (void *) &foo;
}

ypresp_all *ypproc_all_2_svc(ypreq_nokey *nokey, struct svc_req *rqstp)
{
    static ypresp_all result;

    if (debug_flag)
    {
	fprintf(stderr, "ypproc_all_2_svc():\n");
	fprintf(stderr, "\tdomain = \"%s\"\n", nokey->domain);
	fprintf(stderr, "\tmap = \"%s\"\n", nokey->map);
    }

    result.more = FALSE;

    if (!is_valid_domain(nokey->domain))
	result.ypresp_all_u.val.stat = YP_NODOM;
    else
	result.ypresp_all_u.val.stat = YP_BADDB;

    result.ypresp_all_u.val.key.keydat_len = 0;
    result.ypresp_all_u.val.key.keydat_val = NULL;
    result.ypresp_all_u.val.val.valdat_len = 0;
    result.ypresp_all_u.val.val.valdat_val = NULL;
    
    return &result;
}

ypresp_master *ypproc_master_2_svc(ypreq_nokey *nokey, struct svc_req *rqstp)
{
    static ypresp_master result;

    if (debug_flag)
    {
	fprintf(stderr, "ypproc_master_2_svc():\n");
	fprintf(stderr, "\tdomain = \"%s\"\n", nokey->domain);
	fprintf(stderr, "\tmap = \"%s\"\n", nokey->map);
    }


    if (!is_valid_domain(nokey->domain))
	result.stat = YP_NODOM;
    else
	result.stat = YP_BADDB;

    result.peer = "foobar.fubar.com";
    
    return &result;
}

ypresp_order *ypproc_order_2_svc(ypreq_nokey *nokey, struct svc_req *rqstp)
{
    static ypresp_order result;

    if (debug_flag)
    {
	fprintf(stderr, "ypproc_order_2_svc():\n");
	fprintf(stderr, "\tdomain = \"%s\"\n", nokey->domain);
	fprintf(stderr, "\tmap = \"%s\"\n", nokey->map);
    }


    if (!is_valid_domain(nokey->domain))
	result.stat = YP_NODOM;
    else
	result.stat = YP_BADDB;

    result.ordernum = 42;
    
    return &result;
}

ypresp_maplist *ypproc_maplist_2_svc(domainname *name, struct svc_req *rqstp)
{
    static ypresp_maplist result;

    if (debug_flag)
    {
	fprintf(stderr, "ypproc_maplist_2_svc():\n");
	fprintf(stderr, "\tdomain = \"%s\"\n", *name);
    }


    if (!is_valid_domain(name))
	result.stat = YP_NODOM;
    else
	result.stat = YP_BADDB;

    result.maps = NULL;
    
    return &result;
}
