#include <device.h>
#include <stddef.h>
#include <string.h>

/*
 * Pseudo-device interface stuff. New devices can be hooked into the chain
 * that's rooted at __devices. All _unx2dos and low level i/o functions use this
 * chain in determining whether files are devices or disk files, as does stat().
 * The major device number of user-supplied devices must *NOT* be 0 or 0xff,
 * both of which are reserved.
 */

static struct _device prn_dev = {
"PRN:", "lp", 0xfffd, NULL, NULL, NULL, NULL, NULL, 0
};

static struct _device aux_dev = {
"AUX:", "tty1", 0xfffe, NULL, NULL, NULL, NULL, NULL, &prn_dev
};

static struct _device con_dev = {
"CON:", "console", 0xffff, NULL, NULL, NULL, NULL, NULL, &aux_dev
};

struct _device *__devices = &con_dev;

/*
 * install a new device
 */

void
_install_device(d)
	struct _device *d;
{
	d->next = __devices;
	__devices = d;
}

/*
 * find a device based on it's file descriptor
 */

struct _device *
_dev_fd(fd)
	int fd;
{
	struct _device *d;

	for (d = __devices; d; d = d->next)
		if (d->dev == fd) break;
	return d;
}

/*
 * find a device based on its DOS or UNIX name.
 */

struct _device *
_dev_dosname(dosnm)
	const char *dosnm;
{
	struct _device *d;

	for (d = __devices; d; d = d->next) {
		if (!strcmp(dosnm, d->dosnm)) break;
	}
	return d;
}

struct _device *
_dev_unxname(unm)
	const char *unm;
{
	struct _device *d;

	for (d = __devices; d; d = d->next) {
		if (!strcmp(unm, d->unxnm)) break;
	}
	return d;
}
