
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

#ifdef DEBUG
	#define LOGFILE	"c:\\gemsys\\magic\\xtension\\bnetdebg.log"
	#define LOGBACK	"c:\\gemsys\\magic\\xtension\\bnetdebg.olg"
	#include <stdarg.h>
#endif /* DEBUG */
#define reg		register
#define MAIN_BODY

#include "bnet_xfs.h"
#include <transprt.h>
#include <port.h>
#include <layer.h>

static WORD	wait_for_key;
static char	mountname[256];

DRV_LIST	*sting_drivers;
TPL			*tpl;
STX			*stx;
PORT		*port;
DRIVER		*driver;
LAYER		*layer;

#ifdef DEBUG
	static char	logfile[256];
	static char logback[256];
#endif

static long *get_cookiejar (void)
{
	reg long old_stack, *jar;

	if (Super((void *)1L) == 0L)
    {
		old_stack = Super (NULL);
		jar = *((long **) 0x5a0L);
		Super ((void *) old_stack);
	}
	else
		jar = *((long **) 0x5a0L);
	return (jar);
}

LONG	*get_cookie (ULONG  cookie, ULONG  *value)
{
	reg long *cookiejar = get_cookiejar();

	if (cookiejar)
	{
		while (*cookiejar)
		{
			if (*cookiejar==cookie)
			{
				if (value)
					*value = *++cookiejar;
				return (cookiejar);
			}
			cookiejar += 2;
		}
	}
	return (NULL);
}

WORD	new_cookie (COOKIE *entry)
{
	reg long *cookiejar = get_cookiejar();
	reg int  act_row = 0;

	if (cookiejar)
	{
		while (*cookiejar)
		{
			cookiejar+=2;
			act_row++;
		}

		if (act_row < cookiejar[1])
		{
			cookiejar[2] = cookiejar[0];
			cookiejar[3] = cookiejar[1];

			*cookiejar++ = *((long *) entry)++;
			*cookiejar++ = *((long *) entry)++;
			return(TRUE);
		}
	}
	return(FALSE);
}

int 	is_STING (void)
{
	int 	res = 0;

	 if (! get_cookie ('STiK', (ULONG *)&sting_drivers) )
	 	return (res);

	if (sting_drivers == 0L)
		return (res);

	if (strcmp (sting_drivers->magic, MAGIC) != 0)
		return (res);

	stx = (STX *) (*sting_drivers->get_dftab) (MODULE_DRIVER);
	if (stx == (STX *) NULL)
		return (res);

	query_chains ((void *)&port, (void *)&driver, (void *)&layer);

	tpl = (TPL *) (*sting_drivers->get_dftab) (TRANSPORT_DRIVER);
	if (tpl == (TPL *) NULL)
		return (res);
	return (TRUE);
}

void	load_bnet_inf (void)
{
	static char	filename[128], buf[256];
	LONG		err;
	WORD		handle;
	char		*prgname, *end_path, *arg, *pos;

	wait_for_key = 0;	/* Normally 0	*/

	strcpy (filename, "\\gemsys\\magic\\xtension\\");
	end_path = strrchr(filename, '\\');

	strcat (filename, "bnet_xfs.inf");

	if (((err = Fopen (filename, FO_READ)) < 0L) && (!end_path ||
		(((err = Fopen (end_path, FO_READ)) < 0L) &&
		((err = Fopen (++end_path, FO_READ)) < 0L))))
	{
		return;
	}
	handle = (WORD)err;
	while (readline (handle, buf))
	{
		if (! *buf )
			continue;
		if ((arg = strchr (buf, '=')) == NULL)
		{
	invalid_line:
			if (arg != NULL)
				*arg = '=';
			Cconws ("Invalid line in BNET_INF file (ignored):\r\n");
			Cconws (buf);
			Cconws ("\r\n");
			wait_for_key = 1;
			continue;
		}
		*arg = 0;

		if (!arg[1])
			goto invalid_line;
		if (! stricmp (buf, "bnet_drive") )
		{
			if (arg[2])
				goto invalid_line;
			arg[1] &= ~32;
			if ((arg[1] < 'A') || (arg[1] > 'Z') || (arg[1] == 'U'))
				goto invalid_line;
			bnet_drive = arg[1] - 'A';
			continue;
		}
		if (! stricmp (buf, "mount_as") )
		{
			strcpy (mountname, &arg[1]);
			continue;
		}
		if (! stricmp (buf, "v_label") )
		{
			volume_label[32] = 0;
			strncpy (volume_label, &arg[1], 32L);
			continue;
		}
#ifdef DEBUG
		if (!stricmp (buf, "logfile") )
		{
			strcpy (logfile, &arg[1]);
			strcpy(logback, "");
			continue;
		}
		if (! stricmp (buf, "logbackup") )
		{
			strcpy (logback, &arg[1]);
			continue;
		}
#endif
		goto invalid_line;
	}
	Fclose (handle);
}

WORD readline (WORD handle, char *buffer)
{
    WORD    count;
    LONG	fpos, add, bytes_read;

    for (;;)
    {
		fpos = Fseek (0L, handle, 1);
		if (fpos < 0L)
			return(0);
		if ((bytes_read = Fread (handle, 255, buffer)) <= 0L)
		{
			return (0);
		}
        count = 0;
		add = 1L;
        for (;;)
        {
        	if (count == bytes_read)
        	{
        		add = 0L;
        		break;
        	}
            if (buffer[count] == '\n')
                break;
            if (count == 255)
                return(0);
            if (buffer[count] == '\t')
            	buffer[count] = ' ';
            count++;
        }
        if (Fseek ((LONG)count + fpos + add, handle, 0) < 0L)
        {
        	return (0);
        }
        if (count)
        {
            if (buffer[count - 1] == '\r')
                count--;
        }
        buffer[count] = 0;
        if (*buffer != '#')
            break;
    }
    return (1);
}

/*
 * get_and_set_drive
 *
 * If there isn't one in bnet_drv.inf file
 * (2 = C, 3 = D, etc.)
 */
LONG get_and_set_drive (void)
{
	LONG	*_drvbits, i;

	_drvbits = (LONG *)0x4c2;
	for (i = 2L; i < 26L; i++)
	{
		if ((i != (LONG)('U' - 'A')) && !(*_drvbits & (1L << i)))
		{
			*_drvbits |= (1L << i);
			break;
		}
	}
	if (i == 26L)
		return (-1L);
	else
		return (i);
}

/*
 * set_bnet_drive
 */
LONG set_bnet_drive (void)
{
	LONG	*_drvbits;

	_drvbits = (LONG *)0x4c2;
	if (*_drvbits & (1L << bnet_drive))
	{
/*
 * Can't believe it (we can't have drive B for now !!)
 */
		if ((bnet_drive != 1) || (*(WORD *)0x4a6 > 1))
			return(0L);
	}
	*_drvbits |= (1L << bnet_drive);
	return(1L);
}

/*
 * Pdomain_gemdos
 * Actual Domain (0 = TOS, 1 = MiNT)
 */
LONG Pdomain_gemdos(WORD domain)
{
	return (gemdos (281, domain));
}

#pragma warn -par
LONG Pdomain_kernel (WORD ignore)
{
	LONG	domain;

	domain = (kernel->proc_info)(1, *(real_kernel->act_pd));
	return (domain);
}
#pragma warn .par

/*
 * inc_refcnt for a dir entry
 */
void inc_refcnt (BNETX_FD *dd)
{
	dd->fd_refcnt++;
	if (dd->fd_refcnt > 1)
		return;
	for (dd = dd->fd_parent; dd != NULL; dd = dd->fd_parent)
	{
		dd->fd_is_parent++;
	}
}

/*
 * prepare_dir
 *
 * Initialise a Folder entry
 */

void prepare_dir (DIR_SLOT *dir, WORD maxentries, DIR_SLOT *parent)
{
	(kernel->fast_clrmem)(dir, &dir[maxentries]);
	strcpy (dir[0].de_fname, ".");
	dir[0].de_faddr = (char *)dir;
	dir[0].de_nr = 0;
	dir[0].de_maxnr = maxentries;
	dir[0].de_xattr.mode = S_IFDIR | 0777;
	dir[0].de_xattr.index = (LONG)dir;
	dir[0].de_xattr.dev = bnet_drive;
	dir[0].de_xattr.rdev = bnet_drive;
	dir[0].de_xattr.nlink = 1;
	dir[0].de_xattr.uid = 0;
	dir[0].de_xattr.gid = 0;
	dir[0].de_xattr.size = 0L;
	if (parent != ROOT_DE)
		dir[0].de_xattr.nblocks = 1L;
	else
		dir[0].de_xattr.nblocks = 0L;
	dir[0].de_xattr.mtime = dir[0].de_xattr.atime = dir[0].de_xattr.ctime =
		starttime;
	dir[0].de_xattr.mdate = dir[0].de_xattr.adate = dir[0].de_xattr.cdate =
		startdate;

	dir[0].de_xattr.attr = FA_DIR;
	dir[0].de_xattr.reserved2 = 0;
	dir[0].de_xattr.reserved3[0] = 0L;
	dir[0].de_xattr.reserved3[1] = 0L;

	strcpy (dir[1].de_fname, "..");
	if (parent != ROOT_DE)
	{
		parent[0].de_xattr.atime = parent[0].de_xattr.mtime =
			starttime;
		parent[0].de_xattr.adate = parent[0].de_xattr.mdate =
			startdate;
		dir[1].de_faddr = (char *)parent;
		dir[1].de_nr = 1;
		dir[1].de_maxnr = 0;
		dir[1].de_xattr = parent[0].de_xattr;
	}
	else
	{
		dir[1].de_faddr = (char *)&root_de;
		dir[1].de_nr = 1;
		dir[1].de_maxnr = 0;
		dir[1].de_xattr.mode = S_IFDIR | 0777;
		dir[1].de_xattr.index = (LONG)parent;
		dir[1].de_xattr.dev = bnet_drive;
		dir[1].de_xattr.rdev = bnet_drive;
		dir[1].de_xattr.nlink = 1;
		dir[1].de_xattr.uid = 0;
		dir[1].de_xattr.gid = 0;
		dir[1].de_xattr.size = 0L;
		dir[1].de_xattr.nblocks = 1L;
		dir[1].de_xattr.mtime = dir[1].de_xattr.atime = starttime;
		dir[1].de_xattr.mdate = dir[1].de_xattr.adate = startdate;

		dir[1].de_xattr.ctime = starttime;
		dir[1].de_xattr.cdate = startdate;
		dir[1].de_xattr.attr = FA_DIR;
		dir[1].de_xattr.reserved2 = 0;
		dir[1].de_xattr.reserved3[0] = 0L;
		dir[1].de_xattr.reserved3[1] = 0L;
	}
}

DIR_SLOT *find_obj (BNETX_FD *dd, char *pathname, WORD spos,
	WORD s_or_e, WORD maybe_dir)
{
	WORD		i, max;
	DIR_SLOT	*search;
	char		*temp,
				*dos;

	if (!is_dir (dd->fd_file->de_xattr.mode))
		return (NULL);
	if (! *pathname && maybe_dir)
		return (dd->fd_file);

	temp = (kernel->int_malloc)();
	dos = (kernel->int_malloc)();
	temp[32] = 0;
	strncpy (temp, pathname, 32L);
	search = (DIR_SLOT *)dd->fd_file->de_faddr;
	max = search[0].de_maxnr;

	if ((Pdomain(-1) == EINVFN) || (Pdomain(-1) == 1) ||
		(s_or_e == FF_SEARCH))
	{
		for (i = spos; i < max; i++)
		{
			if (search[i].de_faddr == NULL)
				continue;
			if (!strcmp (temp, search[i].de_fname))
			{
				(kernel->int_mfree)(temp);
				(kernel->int_mfree)(dos);
				return (&search[i]);
			}
		}
	}

	if ((Pdomain(-1) == 1) ||
		((Pdomain(-1) == EINVFN) && (s_or_e == FF_EXIST)))
	{
		(kernel->int_mfree)(temp);
		(kernel->int_mfree)(dos);
		return (NULL);
	}
 /* Now check for TOS domain	*/
	if (Pdomain(-1) == 0)
	{
	/*	strlwr (temp); */
		for (i = spos; i < max; i++)
		{
			if (search[i].de_faddr == NULL)
				continue;
			if (!strcmp (temp, search[i].de_fname))
			{
				(kernel->int_mfree)(temp);
				(kernel->int_mfree)(dos);
				return (&search[i]);
			}
		}

		if (s_or_e == FF_EXIST)
		{
			(kernel->int_mfree)(temp);
			(kernel->int_mfree)(dos);
			return (NULL);
		}
	}

	tostrunc (temp, pathname, 0);
	for (i = spos; i < max; i++)
	{
		if (search[i].de_faddr == NULL)
			continue;
		tostrunc(dos, search[i].de_fname, 0);
		TRACE(("find_obj: temp = %S, dos = %S\r\n", 2, temp, dos));
		if (!strcmp (temp, dos))
		{
			(kernel->int_mfree)(temp);
			(kernel->int_mfree)(dos);
			return (&search[i]);
		}
	}
 /* Not found */
	(kernel->int_mfree)(temp);
	(kernel->int_mfree)(dos);
	return (NULL);
}

/*
 * findfd (find a free FD)
 */

BNETX_FD *findfd (DIR_SLOT *fname)
{
	WORD	i;

#if 1
/*
 * Ist ein Verzeichniseintrag gegeben, zun„chst schauen, ob einer der
 * FDs bereits durch ihn belegt ist. Falls ja, diesen FD liefern.
 * I have no idea what he means here...
 */
	if (fname != NULL)
	{
		for (i = 0; i < MAX_FD; i++)
		{
			if (fd[i].fd_file == fname)
				return (&fd[i]);
		}
	}
#endif

	for (i = 0; i < MAX_FD; i++)
	{
		if (fd[i].fd_file == NULL)
		{
			(kernel->fast_clrmem)(&fd[i], &fd[i + 1]);
			return (&fd[i]);
		}
	}
	return(NULL);
}

/*
 * new_file
 */
DIR_SLOT *new_file (BNETX_FD *curr, char *name)
{
	DIR_SLOT	*dir,
				*new_dir;
	WORD		i,
				max;

	if (! check_name (name))
		return(NULL);
	dir = (DIR_SLOT *)curr->fd_file->de_faddr;

	max = dir[0].de_maxnr;
	for (i = 2; i < max; i++)
	{
		if (dir[i].de_faddr == NULL)
			break;
	}
	if (i == max)
	{
		new_dir = &def_dir[0];	/* btest */
		memcpy (new_dir, dir, dir[0].de_maxnr * sizeof(DIR_SLOT) );
		dir = new_dir;
		dir[0].de_maxnr += (WORD)MAXDRIVES;	/* DEF_DIR; */
		dir[0].de_xattr.nblocks++;
		dir[0].de_faddr = (char *)new_dir;
		dir[0].de_xattr.index = (LONG)new_dir;
		curr->fd_file->de_maxnr = dir[0].de_maxnr;
		curr->fd_file->de_xattr.nblocks = dir[0].de_xattr.nblocks;
		curr->fd_file->de_faddr = (char *)new_dir;
		curr->fd_file->de_xattr.index = (LONG)new_dir;
	}
	(kernel->fast_clrmem)(&dir[i], &dir[i + 1]);
	strncpy (dir[i].de_fname, name, 32L);

	dir[i].de_nr = i;
	dir[i].de_xattr.atime = dir[i].de_xattr.mtime =
		dir[i].de_xattr.ctime = starttime;
	dir[i].de_xattr.adate = dir[i].de_xattr.mdate =
		dir[i].de_xattr.cdate = startdate;
	dir[i].de_xattr.dev = bnet_drive;
	dir[i].de_xattr.rdev = bnet_drive;
	dir[i].de_xattr.nlink = 1;
	dir[i].de_xattr.blksize = SECSIZ;
	return (&dir[i]);
}


WORD dir_is_open (DIR_SLOT *dir)
{
	WORD	i;

	for (i = 0; i < MAX_DHD; i++)
	{
		if (dhd[i].dhd_dir == dir)
			return (1);
	}
	return (0);
}

WORD check_name (char *name)
{
	WORD	i,
			max,
			check;

	if (!*name)
		return(0);
	max = eight_bit ? 255 : 127;
	for (i = 0; i < strlen (name); i++)
	{
		check = (WORD)name[i] & 0xff;
		if ((check < 32) || (check > max) ||
			(name[i] == '\\'))
		{
			return(0);
		}
	}
	return(1);
}


LONG check_dd (BNETX_FD *dd)
{
	if (dd->fd_dmd != bnet_dmd)
		return (EDRIVE);
	if (!is_dir (dd->fd_file->de_xattr.mode))
		return (EPTHNF);
	return (E_OK);
}

LONG check_fd (BNETX_FD *fd)
{
	if (fd->fd_dmd != bnet_dmd)
		return (EDRIVE);
	if (!is_file (fd->fd_file->de_xattr.mode))
		return (EFILNF);
	return (E_OK);
}

/* Thomas	*/
LONG work_entry (BNETX_FD *dd, char *name, char **symlink,
	WORD writeflag, LONG par1, LONG par2,
	LONG (*action)(DIR_SLOT *entry, LONG par1, LONG par2))
{
	DIR_SLOT	*found,
				*help;
	LONG		retcode;
	WORD		i,
				max;
	XATTR		new;

	if (check_dd(dd) < 0)
	{
		if (action == NULL)
			return (EINVFN);
		else
			return(check_dd(dd));
	}
/* Search entry */
	if ((found = find_obj (dd, name, 0, FF_SEARCH, 1)) == NULL)
	{
		if (action == NULL)
			return (EINVFN);
		else
			return (EFILNF);
	}
/* Test for symbolic Link */
	if (is_link (found->de_xattr.mode) && (symlink != NULL))
	{
		TRACE(("work_entry: Folge symbolischem Link auf %S!\r\n", 1,
			&found->de_faddr[2]));
		*symlink = found->de_faddr;
		return (ELINK);
	}
	if (action == NULL)
		return (EINVFN);

	if (writeflag && (dd->fd_file->de_faddr != found->de_faddr) &&
		!waccess(dd->fd_file))
	{
		return (EACCDN);
	}

	retcode = (action)(found, par1, par2);
	if ((retcode < 0L) || !writeflag)
		return (retcode);

	if (!is_dir (found->de_xattr.mode))
		return (retcode);

	new = found->de_xattr;
	if (!strcmp (found->de_fname, "."))
		found = dd->fd_file;
	if (!strcmp (found->de_fname, ".."))
	{
		if (dd->fd_parent == NULL)
			return (retcode);
		found = dd->fd_parent->fd_file;
	}
	found->de_xattr = new;
	found = (DIR_SLOT *)found->de_faddr;
	found->de_xattr = new;
	max = found->de_maxnr;
	for (i = 2; i < max; i++)
	{
		if ((found[i].de_faddr != NULL) && is_dir(found[i].de_xattr.mode))
		{
			help = (DIR_SLOT *)found[i].de_faddr;
			help[1].de_xattr = new;
		}
	}
	return (retcode);
}

void tostrunc (char *dest, char *src, WORD wildcards)
{
	WORD	i;
	char	*lastdot, temp[] = "a";

	TRACE(("tostrunc: %S -> %L\r\n", 2, src, dest));

	if (!strcmp(src, ".") || !strcmp(src, ".."))
	{
		strcpy (dest, src);
		return;
	}

	lastdot = strrchr(src, '.');
	if (lastdot != NULL)
	{
		if ((lastdot == src) || !lastdot[1])
			lastdot = NULL;
	}
	strcpy (dest, "");
	for (i = 0; i < 8; i++)
	{
		if (!*src || (src == lastdot))
			break;
		if (*src == '.')
			strcat (dest, ",");
		else
		{
			if (strchr("_!@#$%^&()+-=~`;\'\",<>|[]{}", *src) ||
				isalnum (*src) || (wildcards && ((*src == '*') ||
				(*src == '?'))))
			{
				*temp = toupper(*src);
				strcat (dest, temp);
			}
			else
				strcat (dest, "X");
		}
		src++;
	}
	if (lastdot)
	{
		strcat (dest, ".");
		src = lastdot;
		src++;
		for (i = 0; i < 3; i++)
		{
			if (!*src)
				break;
			if (strchr("_!@#$%^&()+-=~`;\'\",<>|[]{}", *src) ||
				isalnum(*src) || (wildcards && ((*src == '*') ||
				(*src == '?'))))
			{
				*temp = toupper (*src);
				strcat (dest, temp);
			}
			else
				strcat (dest, "X");
			src++;
		}
	}
}

/*
 * fill_tosname
 *
 * Example:	(Thomas Binder)
 * "PC.PRG" -> "PC      .PRG"
 * "FOO.C" -> "FOO     .C  "
 * "AUTO" -> "AUTO    .   "
 * "*.TXT" -> "????????.TXT"
 * "ABC*.?X*" -> "ABC?????.?X?"
 *
 */
void fill_tosname (char *dest, char *src)
{
	WORD	i;
	char	*dot;

	if (!strcmp (src, "."))
	{
		strcpy (dest, ".       .   ");
		return;
	}
	if (!strcmp (src, ".."))
	{
		strcpy (dest, "..      .   ");
		return;
	}

	strcpy (dest, "        .   ");

	dot = strchr(src, '.');
	for (i = 0; *src && (src != dot); i++)
		dest[i] = *src++;

	if (dot != NULL)
	{
		src = ++dot;
		for (i = 0; *src; i++)
			dest[9 + i] = *src++;
	}

	for (i = 0; i < 8; i++)
	{
		if (dest[i] == '*')
		{
			memset(&dest[i], '?', (LONG)(8 - i));
			break;
		}
	}
	for (i = 9; i < 12; i++)
	{
		if (dest[i] == '*')
		{
			memset (&dest[i], '?', (LONG)(12 - i));
			break;
		}
	}
}

WORD match_tosname(char *to_check, char *sample)
{
	WORD	i;

	TRACE(("match_tosname: %S, %S\r\n", 2, to_check, sample));

	for (i = 0; i < 12; i++)
	{
		if (sample[i] != '?')
			if (sample[i] != to_check[i])
			{
				TRACE(("Warnix\r\n", 0));
				return (0);
			}
	}
	return (1);
}

/*
 * Extensions for automatic exec bit set (Thomas Binder)
 */
static char	*xext[] = {"sot.", "ptt.", "grp.", "ppa.", "ptg.",
	"cca."};

WORD has_xext (char *name)
{
	char	*temp;
	WORD	i;

	if (Pdomain (-1) == 1)
		return (0);
	temp = (kernel->int_malloc)();
	temp[32] = 0;
	strncpy (temp, name, 32L);
	strrev (temp);
	for (i = 0; i < (sizeof(xext) / sizeof(char *)); i++)
	{
		if (!strnicmp (temp, xext[i], strlen(xext[i])))
		{
			(kernel->int_mfree)(temp);
			return (1);
		}
	}
	(kernel->int_mfree)(temp);
	return (0);
}

#ifdef DEBUG

#undef O_RDWR
#undef O_APPEND
#undef O_CREAT
#define O_RDWR		0x02
#define O_APPEND	0x08
#define O_CREAT		0x200

/*
 * MiNT (or Thomas) trace routine (depends who wrote it first ! )
 */

void trace (char *format, WORD params, ...)
{
	va_list		args;
	static char	output[128];
	static LONG	out[10];
	WORD		i,
				handle;
	LONG		err;

	va_start (args, params);
	params = (params > 10) ? 10 : params;
	for (i = 0; i < params; i++)
		out[i] = va_arg(args, LONG);
	va_end (args);
	(kernel->_sprintf)(output, format, out);
	if (debug_to_screen)
		Cconws (output);
	else
	{
		if ((err = Fopen (logfile, O_RDWR|O_APPEND|O_CREAT)) >= 0L)
		{
			handle = (WORD)err;
			Fwrite (handle, strlen(output), output);
			Fclose (handle);
		}
		else
			Cconws (output);
	}
}
#endif /* DEBUG */



void	creat_drives (X_NOD *nodes, BNETX_FD *dd, int host)
{
	DIR_SLOT	*entry, *new;
	WORD 	i = 0;
	char	drive_p[] = "Ax\0";

	new = &remote[host][0];	/* test */
	while (nodes->nodes[host][i])
	{
		if (i >= MAXDRIVES - 1)
			break;
		*drive_p = nodes->nodes[host][++i];
		if (! *drive_p)
			break;
		if (find_obj (dd, drive_p, 0, FF_EXIST, 0) != NULL)
			continue;
		if ((entry = new_file (dd, drive_p)) == NULL)
		{
			Cconws (" Failed to create dir \r\n");
			continue;
		}

	/*	(kernel->fast_clrmem)(new, &new[DEFAULTDIR]); */
	/*	(kernel->fast_clrmem)(new, &new[2]);	 test */
	/*	prepare_dir (new, (WORD)DEFAULTDIR, (DIR_SLOT *)dd->fd_file->de_faddr); */
		prepare_dir (new, 2, (DIR_SLOT *)dd->fd_file->de_faddr); 	/* test */
		entry->de_faddr = (char *)new;
		entry->de_xattr.mode = S_IFDIR | 0777;
		entry->de_xattr.index = (LONG)new;
		entry->de_xattr.size = 0L;
		entry->de_xattr.nblocks = 1L;
		entry->de_xattr.attr = FA_DIR;
		entry->de_host = host;
		new += 2;	/* test */
	}
}

/* ------------------- XFS initialization -------------------- */

WORD	main (void)
{
	char	help[2];

	if (! get_cookie ('MagX', NULL))
	{
		Cconws (" BNET-XFS only works with MagiC 3 or better!\r\n");
		Cconws ("Please press any key!\r\n");
		Cnecin ();
		return (-1);
	}
	Cconws("\r\n\33pBNET-XFS dated "__DATE__"\33q\r\n");
	Cconws("(c) 1997-1998 by Vassilis Papathanassiou\r\n");

/* Set parameters to default values */

	bnet_drive = -1;
	strcpy (mountname, "");
	strcpy (volume_label, "");
	eight_bit = 0;
#ifdef DEBUG
	strcpy (logfile, LOGFILE);
#ifdef LOGBACK
	strcpy (logback, "");
#else
	strcpy (logback, LOGBACK);
#endif /* LOGBACK */
#endif /* DEBUG */

	load_bnet_inf();

	if (bnet_drive < 0)
	{
		if ((bnet_drive = (WORD)Supexec (get_and_set_drive)) == -1)
		{
			Cconws("BNET-XFS Installation failed (no free drive)!r\n");
			Cconws("Please press any key!\r\n");
			Cnecin();
			return(-1);
		}
	}
	else
	{
		if (Supexec (set_bnet_drive) == 0L)
		{
			Cconws("Installation failed (drive already in use)!\r\n");
			Cconws("Please press any key!\r\n");
			Cnecin();
			return(-1);
		}
	}

	if ((kernel = (THE_MX_KERNEL *)Dcntl(KER_GETINFO, NULL, NULL)) == NULL)
	{
		Cconws("Installation failed (kernel structure unavailable)!\r\n");
		Cconws("Please press any key!\r\n");
		Cnecin();
		return(-1);
	}
	if (kernel->int_msize < 34)
	{
		Cconws("Installation failed (kernel blocksize too small)!\r\n");
		Cconws("Please press any key!\r\n");
		Cnecin();
		return(-1);
	}

	if ((kernel = install_xfs (&bnet_xfs)) == NULL)
	{
		Cconws("Installation failed (MagiC error)!\r\n");
		Cconws("Please press any key!\r\n");
		Cnecin();
		return(-1);
	}

/*	Lets install the BNeT cookie now	*/
	bnet_cook.cookie_id = 'BNeT';
	bnet_cook.cookie_value = (LONG)bnet_drive;
	if (! new_cookie (&bnet_cook) )
	{
		Cconws ("What ? No place for cookie !\r\n");
		Cconws("Press any key (and make it BIGGER)!\r\n");
		Cnecin();
		return(-1);
	}

	if (bnet_drive == 1) /* Highly unlikely but Thomas spoted it! */
	{
	#define Fsymlink(old, new)	gemdos(0x12e, (char *)old, (char *)new)
		Fsymlink("B:\\", "U:\\b");
	}
	Cconws ("Installed as U:\\");
	if (*mountname)
	{
		Dsetdrv('U' - 'A');
		Dsetpath("\\");
		help[0] = bnet_drive + 65;
		help[1] = 0;
		if (Frename (0, help, mountname) != 0L)
		{
			Cconws (help);
			Cconws ("! (Frename failed)\r\n");
			wait_for_key = 1;
		}
		else
		{
			Cconws (mountname);
			Cconws ("!\r\n");
		}
	}
	else
	{
		Cconout (65 + bnet_drive);
		Cconws ("!\r\n");
	}
#ifdef DEBUG
	Cconws("MagiC-Kernel version ");
	Cconout(48 + real_kernel->version);
	Cconws("\r\nDebug-output to ");
	if (Kbshift(-1) & 31)
	{
		debug_to_screen = 1;
		Cconws("screen\r\n");
	}
	else
	{
		if (*logback)
		{
			Fdelete (logback);
			Frename (0, logfile, logback);
		}
		debug_to_screen = 0;
		Cconws (logfile);
		Cconws ("\r\n");
	}
#endif

	Pdomain = Pdomain_gemdos;
	if ((real_kernel->version >= 2) && ((kernel->proc_info)(0, _BasPag) >= 2))
	{
		Pdomain = Pdomain_kernel;
	}

/* Get start date and time for the root dir */
	starttime = Tgettime();
	startdate = Tgetdate();
	if (wait_for_key)
	{
		Cconws("Please press any key!\r\n");
		Cnecin();
	}
	Ptermres (_PgmSize, 0);
	return (0);		/* XFS installed successfully! */
}

/* ======================== End of XFS_UTIL.C ==========================*/
