/* ----------------------------------------------------------------------- *
 *   
 *  lookup_hosts.c - module for Linux automount to mount the exports
 *                      from a given host
 *
 *   Copyright 2005 Ian Kent <raven@themaw.net>
 *
 *   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, Inc., 675 Mass Ave, Cambridge MA 02139,
 *   USA; either version 2 of the License, or (at your option) any later
 *   version; incorporated herein by reference.
 *
 * ----------------------------------------------------------------------- */

#include <stdio.h>
#include <malloc.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <netdb.h>

/* 
 * Avoid annoying compiler noise by using an alternate name for
 * typedef name in mount.h
 */
#define name __dummy_type_name
#include "mount.h"
#undef name

#define MODULE_LOOKUP
#include "automount.h"
#include "nsswitch.h"

#define MAPFMT_DEFAULT "sun"
#define MODPREFIX "lookup(hosts): "

pthread_mutex_t hostent_mutex = PTHREAD_MUTEX_INITIALIZER;

struct lookup_context {
	struct parse_mod *parse;
};

int lookup_version = AUTOFS_LOOKUP_VERSION;	/* Required by protocol */

exports rpc_get_exports(const char *host, long seconds, long micros, unsigned int option);
void rpc_exports_free(exports list);

int lookup_init(const char *mapfmt,
		int argc, const char *const *argv, void **context)
{
	struct lookup_context *ctxt;
	char buf[MAX_ERR_BUF];

	*context = NULL;

	ctxt = malloc(sizeof(struct lookup_context));
	if (!ctxt) {
		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
		logerr(MODPREFIX "malloc: %s", estr);
		return 1;
	}

	mapfmt = MAPFMT_DEFAULT;

	ctxt->parse = open_parse(mapfmt, MODPREFIX, argc, argv);
	if (!ctxt->parse) {
		logerr(MODPREFIX "failed to open parse context");
		free(ctxt);
		return 1;
	}

	*context = ctxt;

	return 0;
}

int lookup_reinit(const char *mapfmt,
		  int argc, const char *const *argv, void **context)
{
	struct lookup_context *ctxt = (struct lookup_context *) *context;
	int ret;

	mapfmt = MAPFMT_DEFAULT;

	ret = reinit_parse(ctxt->parse, mapfmt, MODPREFIX, argc, argv);
	if (ret)
		return 1;

	return 0;
}

int lookup_read_master(struct master *master, time_t age, void *context)
{
	return NSS_STATUS_UNKNOWN;
}

static char *get_exports(struct autofs_point *ap, const char *host)
{
	char buf[MAX_ERR_BUF];
	char *mapent;
	exports exp, this;

	debug(ap->logopt, MODPREFIX "fetchng export list for %s", host);

	exp = rpc_get_exports(host, 10, 0, RPC_CLOSE_NOLINGER);

	mapent = NULL;
	this = exp;
	while (this) {
		if (mapent) {
			int len = strlen(mapent) + 1;

			len += strlen(host) + 2*(strlen(this->ex_dir) + 2) + 3;
			mapent = realloc(mapent, len);
			if (!mapent) {
				char *estr;
				estr = strerror_r(errno, buf, MAX_ERR_BUF);
				error(ap->logopt, MODPREFIX "malloc: %s", estr);
				rpc_exports_free(exp);
				return NULL;
			}
			strcat(mapent, " \"");
			strcat(mapent, this->ex_dir);
			strcat(mapent, "\"");
		} else {
			int len = 2*(strlen(this->ex_dir) + 2) + strlen(host) + 3;

			mapent = malloc(len);
			if (!mapent) {
				char *estr;
				estr = strerror_r(errno, buf, MAX_ERR_BUF);
				error(ap->logopt, MODPREFIX "malloc: %s", estr);
				rpc_exports_free(exp);
				return NULL;
			}
			strcpy(mapent, "\"");
			strcat(mapent, this->ex_dir);
			strcat(mapent, "\"");
		}
		strcat(mapent, " \"");
		strcat(mapent, host);
		strcat(mapent, ":");
		strcat(mapent, this->ex_dir);
		strcat(mapent, "\"");

		this = this->ex_next;
	}
	rpc_exports_free(exp);

	if (!mapent)
		error(ap->logopt, MODPREFIX "exports lookup failed for %s", host);

	return mapent;
}

static int do_parse_mount(struct autofs_point *ap, struct map_source *source,
			  const char *name, int name_len, char *mapent,
			  struct lookup_context *ctxt)
{
	int ret;

	master_source_current_wait(ap->entry);
	ap->entry->current = source;

	ret = ctxt->parse->parse_mount(ap, name, name_len,
				 mapent, ctxt->parse->context);
	if (ret) {
		struct mapent_cache *mc = source->mc;

		/* Don't update negative cache when re-connecting */
		if (ap->flags & MOUNT_FLAG_REMOUNT)
			return NSS_STATUS_TRYAGAIN;
		cache_writelock(mc);
		cache_update_negative(mc, source, name, ap->negative_timeout);
		cache_unlock(mc);
		return NSS_STATUS_TRYAGAIN;
	}
	return NSS_STATUS_SUCCESS;
}

static void update_hosts_mounts(struct autofs_point *ap,
				struct map_source *source, time_t age,
				struct lookup_context *ctxt)
{
	struct mapent_cache *mc;
	struct mapent *me;
	char *mapent;
	int ret;

	mc = source->mc;

	pthread_cleanup_push(cache_lock_cleanup, mc);
	cache_writelock(mc);
	me = cache_lookup_first(mc);
	while (me) {
		/* Hosts map entry not yet expanded or already expired */
		if (!me->multi)
			goto next;

		debug(ap->logopt, MODPREFIX "get list of exports for %s", me->key);

		mapent = get_exports(ap, me->key);
		if (mapent) {
			cache_update(mc, source, me->key, mapent, age);
			free(mapent);
		}
next:
		me = cache_lookup_next(mc, me);
	}
	pthread_cleanup_pop(1);

	pthread_cleanup_push(cache_lock_cleanup, mc);
	cache_readlock(mc);
	me = cache_lookup_first(mc);
	while (me) {
		/*
		 * Hosts map entry not yet expanded, already expired
		 * or not the base of the tree
		 */
		if (!me->multi || me->multi != me)
			goto cont;

		debug(ap->logopt, MODPREFIX
		      "attempt to update exports for %s", me->key);

		master_source_current_wait(ap->entry);
		ap->entry->current = source;
		ap->flags |= MOUNT_FLAG_REMOUNT;
		ret = ctxt->parse->parse_mount(ap, me->key, strlen(me->key),
					       me->mapent, ctxt->parse->context);
		if (ret)
			warn(ap->logopt, MODPREFIX
			     "failed to parse mount %s", me->mapent);
		ap->flags &= ~MOUNT_FLAG_REMOUNT;
cont:
		me = cache_lookup_next(mc, me);
	}
	pthread_cleanup_pop(1);
}

int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
{
	struct lookup_context *ctxt = (struct lookup_context *) context;
	struct map_source *source;
	struct mapent_cache *mc;
	struct hostent *host;
	int status;

	source = ap->entry->current;
	ap->entry->current = NULL;
	master_source_current_signal(ap->entry);

	mc = source->mc;

	debug(ap->logopt, MODPREFIX "read hosts map");

	/*
	 * If we don't need to create directories then there's no use
	 * reading the map. We always need to read the whole map for
	 * direct mounts in order to mount the triggers.
	 */
	if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT) {
		debug(ap->logopt, MODPREFIX
		      "map not browsable, update existing host entries only");
		update_hosts_mounts(ap, source, age, ctxt);
		source->age = age;
		return NSS_STATUS_SUCCESS;
	}

	status = pthread_mutex_lock(&hostent_mutex);
	if (status) {
		error(ap->logopt, MODPREFIX "failed to lock hostent mutex");
		return NSS_STATUS_UNAVAIL;
	}

	sethostent(0);
	while ((host = gethostent()) != NULL) {
		pthread_cleanup_push(cache_lock_cleanup, mc);
		cache_writelock(mc);
		cache_update(mc, source, host->h_name, NULL, age);
		cache_unlock(mc);
		pthread_cleanup_pop(0);
	}
	endhostent();

	status = pthread_mutex_unlock(&hostent_mutex);
	if (status)
		error(ap->logopt, MODPREFIX "failed to unlock hostent mutex");

	update_hosts_mounts(ap, source, age, ctxt);
	source->age = age;

	return NSS_STATUS_SUCCESS;
}

int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *context)
{
	struct lookup_context *ctxt = (struct lookup_context *) context;
	struct map_source *source;
	struct mapent_cache *mc;
	struct mapent *me;
	char *mapent = NULL;
	int mapent_len;
	time_t now = monotonic_time(NULL);
	int ret;

	source = ap->entry->current;
	ap->entry->current = NULL;
	master_source_current_signal(ap->entry);

	mc = source->mc;

	/* Check if we recorded a mount fail for this key anywhere */
	me = lookup_source_mapent(ap, name, LKP_DISTINCT);
	if (me) {
		if (me->status >= monotonic_time(NULL)) {
			cache_unlock(me->mc);
			return NSS_STATUS_NOTFOUND;
		} else {
			struct mapent_cache *smc = me->mc;
			struct mapent *sme;

			if (me->mapent)
				cache_unlock(smc);
			else {
				cache_unlock(smc);
				cache_writelock(smc);
				sme = cache_lookup_distinct(smc, name);
				/* Negative timeout expired for non-existent entry. */
				if (sme && !sme->mapent) {
					if (cache_pop_mapent(sme) == CHE_FAIL)
						cache_delete(smc, name);
				}
				cache_unlock(smc);
			}
		}
	}

	cache_readlock(mc);
	me = cache_lookup_distinct(mc, name);
	if (!me) {
		cache_unlock(mc);
		/*
		 * We haven't read the list of hosts into the
		 * cache so go straight to the lookup.
		 */
		if (!(ap->flags & MOUNT_FLAG_GHOST)) {
			/*
			 * If name contains a '/' we're searching for an
			 * offset that doesn't exist in the export list
			 * so it's NOTFOUND otherwise this could be a
			 * lookup for a new host.
			 */
			if (*name != '/' && strchr(name, '/'))
				return NSS_STATUS_NOTFOUND;
			goto done;
		}

		if (*name == '/')
			info(ap->logopt, MODPREFIX
			      "can't find path in hosts map %s", name);
		else
			info(ap->logopt, MODPREFIX
			      "can't find path in hosts map %s/%s",
			      ap->path, name);

		debug(ap->logopt,
		      MODPREFIX "lookup failed - update exports list");
		goto done;
	}
	/*
	 * Host map export entries are added to the cache as
	 * direct mounts. If the name we seek starts with a slash
	 * it must be a mount request for one of the exports.
	 */
	if (*name == '/') {
		pthread_cleanup_push(cache_lock_cleanup, mc);
		mapent_len = strlen(me->mapent);
		mapent = malloc(mapent_len + 1);
		if (mapent)
			strcpy(mapent, me->mapent);
		pthread_cleanup_pop(0);
	}
	cache_unlock(mc);

done:
	debug(ap->logopt, MODPREFIX "%s -> %s", name, mapent);

	if (!mapent) {
		/* We need to get the exports list and update the cache. */
		mapent = get_exports(ap, name);

		/* Exports lookup failed so we're outa here */
		if (!mapent)
			return NSS_STATUS_UNAVAIL;

		cache_writelock(mc);
		cache_update(mc, source, name, mapent, now);
		cache_unlock(mc);
	}

	ret = do_parse_mount(ap, source, name, name_len, mapent, ctxt);

	free(mapent);

	return ret;
}

int lookup_done(void *context)
{
	struct lookup_context *ctxt = (struct lookup_context *) context;
	int rv = close_parse(ctxt->parse);
	free(ctxt);
	return rv;
}
