/* @(#)bcrypt.c	1.12 98/10/09 Copyright 1988 J. Schilling */
#ifndef lint
static	char sccsid[] =
	"@(#)bcrypt.c	1.12 98/10/09 Copyright 1988 J. Schilling";
#endif
/*
 *	Copyright (c) 1988 J. Schilling
 */
/*
 * 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, 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; see the file COPYING.  If not, write to
 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <mconfig.h>
#include <standard.h>
#include <unixstd.h>
#include <stdxlib.h>
#include <strdefs.h>
#include "fmt.h"

typedef	unsigned long	Ulong;

EXPORT	char	*getnenv	 __PR((const char *, int));
EXPORT	Ulong	my_gethostid	__PR((void));
EXPORT	BOOL	bsecurity	__PR((int));
EXPORT	Ulong	bcrypt		__PR((Ulong));
EXPORT	char	*bmap		__PR((Ulong));
EXPORT	Ulong	bunmap		__PR((const char *));



/*---------------------------------------------------------------------------
|
| Get n'th value from colon separated list in environment
|
+---------------------------------------------------------------------------*/

EXPORT
char *getnenv(name, idx)
	const char	*name;
	int		idx;
{
	static	char rbuf[10];
	char	*ep = getenv(name);
	char	*xp;
	int	i = 0;

	if (!ep)
		return (NULL);

	while (i++ < idx) {
		if ((xp = strchr(ep, ':')) != NULL)
			ep = &xp[1];
		else
			return (NULL);
	}

	strncpy(rbuf, ep, sizeof(rbuf));
	rbuf[sizeof(rbuf)-1] = '\0';

	if ((xp = strchr(rbuf, ':')) != NULL)
		*xp = 0;
	return (rbuf);
}

EXPORT
Ulong my_gethostid()
{
	Ulong	id;

	id = gethostid();
	return (id);
}

EXPORT
BOOL bsecurity(idx)
	int	idx;
{
	Ulong	id;
	char	*sp;

	id = my_gethostid();
	sp = getnenv("SFORMAT_SECURITY", idx);
	while (idx-- >= 0)
		id = bcrypt(id);
	if (!sp || id != bunmap(sp))
		return (FALSE);
	return (TRUE);
}


EXPORT
Ulong bcrypt(i)
	Ulong	i;
{
	register Ulong	k;
	register Ulong	erg;

	k = i + 19991;
	erg = 0;
	do {
		erg += 1 + k / 19;
		erg *= 1 + k % 19;
		k /= 11;
	} while (k != 0);
	return (erg);
}


/*---------------------------------------------------------------------------
|
| Convert unsigned long to string similar to l64a()
|
+---------------------------------------------------------------------------*/

EXPORT
char *bmap(i)
	register Ulong	i;
{
	register int	c;
	static	char	buf[8];
	register char	*bp;

	bp = &buf[7];
	*bp = '\0';
	do {
		c = i % 64;
		i /= 64;
		c += '.';
		if(c > '9')
			c += 7;
		if(c > 'Z')
			c += 6;
		*--bp = c;
	} while (i);
	return (bp);
}


/*---------------------------------------------------------------------------
|
| Convert string to unsigned long similar to a64l()
|
+---------------------------------------------------------------------------*/

EXPORT
Ulong bunmap(s)
	register const char	*s;
{
	register Ulong	l;
	register int	c;

	l = 0L;
	while (*s) {
		c = *s++;
		if(c > 'Z')
			c -= 6;
		if(c > '9')
			c -= 7;
		c -= '.';
		l *= 64;
		l += c;
	}
	return (l);
}
