/*
 *  linux/ibcs/map.c
 *
 *  Copyright (C) 1994  Mike Jagdis (jaggy@purplet.demon.co.uk)
 *
 * $Id$
 * $Source$
 */

#include <linux/sched.h>
#include <linux/net.h>
#include <linux/socket.h>
#include <linux/personality.h>

#include <ibcs/socket.h>
#include <ibcs/map.h>

#ifndef NULL
#define NULL	((void *)0)
#endif


/* Error code maps. */
#include "errmap.inc"

/* Socket subsystem maps. */
#include "sockaf.inc"
#include "sockopt.inc"
#include "sockdom.inc"


int
map_value(struct map_segment *m[], int val, int def) {
	int pers;
	struct map_segment *seg;

	pers = current->personality & PER_MASK;

	/* If no mapping exists in this personality just return the
	 * number we were given.
	 */
	if (!m[pers])
		return val;

	/* Search the map looking for a mapping for the given number. */
	for (seg=m[pers]; seg->start != -1; seg++) {
		if (seg->start <= val && val <= seg->end) {
			/* If the start and end are the same then this
			 * segment has one entry and the map is the value
			 * it maps to. Otherwise if we have a vector we
			 * pick out the relevant value, if we don't have
			 * a vector we give identity mapping.
			 */
			if (seg->start == seg->end)
				return (int)seg->map;
			else
				return (seg->map ? seg->map[val-seg->start] : val);
		}
	}

	/* Number isn't mapped. Returned the requested default. */
	return def;
}


/* Translate the errno numbers from linux to current personality.
 * This should be removed and all other sources changed to call the
 * map function above directly.
 */
int iABI_errors(int errno)
{
	return map_value(err_map, errno, 1);
}
