/*
 * Copyright (c) 2004-2005, 2007-2010
 *	Todd C. Miller <Todd.Miller@courtesan.com>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <config.h>

#include <sys/types.h>
#include <sys/param.h>
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
#  include <stdlib.h>
# endif
#endif /* STDC_HEADERS */
#ifdef HAVE_STRING_H
# include <string.h>
#endif /* HAVE_STRING_H */
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif /* HAVE_STRING_H */
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif /* HAVE_UNISTD_H */

#include "sudo.h"
#include "parse.h"
#include "redblack.h"
#include <gram.h>

/*
 * Globals
 */
struct rbtree *aliases;
unsigned int alias_seqno;

/*
 * Comparison function for the red-black tree.
 * Aliases are sorted by name with the type used as a tie-breaker.
 */
int
alias_compare(v1, v2)
    const void *v1, *v2;
{
    const struct alias *a1 = (const struct alias *)v1;
    const struct alias *a2 = (const struct alias *)v2;
    int res;

    if (v1 == NULL)
	res = -1;
    else if (v2 == NULL)
	res = 1;
    else if ((res = strcmp(a1->name, a2->name)) == 0)
	res = a1->type - a2->type;
    return(res);
}

/*
 * Search the tree for an alias with the specified name and type.
 * Returns a pointer to the alias structure or NULL if not found.
 */
struct alias *
alias_find(name, type)
    char *name;
    int type;
{
    struct alias key;
    struct rbnode *node;
    struct alias *a = NULL;

    key.name = name;
    key.type = type;
    if ((node = rbfind(aliases, &key)) != NULL) {
	    /*
	     * Compare the global sequence number with the one stored
	     * in the alias.  If they match then we've seen this alias
	     * before and found a loop.
	     */
	    a = node->data;
	    if (a->seqno == alias_seqno)
		return(NULL);
	    a->seqno = alias_seqno;
    }
    return(a);
}

/*
 * Add an alias to the aliases redblack tree.
 * Returns NULL on success and an error string on failure.
 */
char *
alias_add(name, type, members)
    char *name;
    int type;
    struct member *members;
{
    static char errbuf[512];
    struct alias *a;

    a = emalloc(sizeof(*a));
    a->name = name;
    a->type = type;
    a->seqno = 0;
    list2tq(&a->members, members);
    if (rbinsert(aliases, a)) {
	snprintf(errbuf, sizeof(errbuf), "Alias `%s' already defined", name);
	alias_free(a);
	return(errbuf);
    }
    return(NULL);
}

/*
 * Apply a function to each alias entry and pass in a cookie.
 */
void
alias_apply(func, cookie)
    int (*func) __P((void *, void *));
    void *cookie;
{
    rbapply(aliases, func, cookie, inorder);
}

/*
 * Returns TRUE if there are no aliases, else FALSE.
 */
int
no_aliases()
{
    return(rbisempty(aliases));
}

/*
 * Free memory used by an alias struct and its members.
 */
void
alias_free(v)
    void *v;
{
    struct alias *a = (struct alias *)v;
    struct member *m;
    struct sudo_command *c;
    void *next;

    efree(a->name);
    for (m = a->members.first; m != NULL; m = next) {
	next = m->next;
	if (m->type == COMMAND) {
		c = (struct sudo_command *) m->name;
		efree(c->cmnd);
		efree(c->args);
	}
	efree(m->name);
	efree(m);
    }
    efree(a);
}

/*
 * Find the named alias, remove it from the tree and return it.
 */
struct alias *
alias_remove(name, type)
    char *name;
    int type;
{
    struct rbnode *node;
    struct alias key, *a;

    key.name = name;
    key.type = type;
    if ((node = rbfind(aliases, &key)) == NULL)
	return(NULL);
    a = rbdelete(aliases, node);
    return(a);
}

void
init_aliases()
{
    if (aliases != NULL)
	rbdestroy(aliases, alias_free);
    aliases = rbcreate(alias_compare);
}
