#include "args.h"

#include "config.h"
/*
 * Copyright (c) 1986, 2014 by The Trustees of Columbia University in
 * the City of New York.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  + Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 *  + Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 *  + Neither the name of Columbia University nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 */

#ifndef lint
static const char *rcsid = "$Header: /usr/local/src/mm/mm-0.94/mm/RCS/alias.c,v 1.2 2005/05/28 22:39:23 beebe Exp $";
#endif

#include "mm.h"
#include "parse.h"

Mail_aliases mail_aliases = { nil, 0 };

static brktab fldbrk = {
    {
	0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x00, 0x3f,
	0x80, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x1f,
    },
    {
	0xff, 0xff, 0xff, 0xff, 0xfb, 0xf9, 0x00, 0x1f,
	0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x1f,
    },
};

static void free_alias ARGS((const char *name));

extern fdb aliasfdb;		/* get from parse.c */

#define pv pv_			/* void warnings about shadowed global */
#define used used_		/* void warnings about shadowed global */

void
#if HAVE_STDC
cmd_define(int n)
#else /* K&R style */
cmd_define(n)
int n;
#endif /* HAVE_STDC */
{
    static char *alias = nil;
    static addresslist alias_addr = { nil, nil };
    keytab *ak;
    static fdb fldfdb = { _CMFLD, CM_SDH, NULL, NULL, "new alias name",
			  NULL, &fldbrk};
    pval pv;
    fdb *used;

    ak = mk_alias_keys();
    aliasfdb._cmdat = (pdat) ak;

    noise("alias");
    if (mail_aliases.count > 0)
	parse(fdbchn(&aliasfdb, &fldfdb, nil), &pv, &used);
    else
	parse(fdbchn(&fldfdb, nil), &pv, &used);
    if (alias)
	free(alias);
    if (used == &aliasfdb) {
	alias = safe_strcpy(ak->_ktwds[pv._pvkey]._kwkwd);
    }
    else {
	if ((int)strlen(atmbuf) < 1)
	    cmerr("Invalid character in alias name");
	alias = safe_strcpy(atmbuf);
    }
    noise("as");
    parse_define(&alias_addr);	/* get an addresslist for it */
    if (alias_addr.first)
	set_alias(safe_strcpy(alias),&alias_addr,MA_USER); /* set new alias */
    else
	free_alias(alias);
    alias_addr.first = alias_addr.last = nil;
    free(alias);
    alias = nil;
}

static void
#if HAVE_STDC
free_alias(const char *name)
#else /* K&R style */
free_alias(name)
const char *name;
#endif /* HAVE_STDC */
{
    mail_alias *ma;
    int i,j;


    if (mail_aliases.count == 0)
	return;

    for(i = 0; i < mail_aliases.count; i++) {
	ma = &mail_aliases.aliases[i];
	if (ustrcmp(ma->name, name) == 0) {
	    free((void *)ma->name);
	    free_addresslist(&ma->alias);
	    for(j = i+1; j < mail_aliases.count; i++, j++) {
		mail_aliases.aliases[i].name =
		    mail_aliases.aliases[j].name;
		mail_aliases.aliases[i].alias =
		    mail_aliases.aliases[j].alias;
		mail_aliases.aliases[i].type =
		    mail_aliases.aliases[j].type;
	    }
	    mail_aliases.count--;
	    return;
	}
    }
}


void
#if HAVE_STDC
set_alias(const char *name, addresslist *addr, int type)
#else /* K&R style */
set_alias(name,addr,type)
const char *name;
addresslist *addr;
int type;
#endif /* HAVE_STDC */
{
    int i;
    free_alias(name);			/* free any old definition */
    i = mail_aliases.count;		/* remember old count */
    mail_aliases.aliases =
	(mail_alias *)safe_realloc(mail_aliases.aliases,
				   (++mail_aliases.count) *
				   sizeof(struct mail_alias));
    mail_aliases.aliases[i].name = name;
    mail_aliases.aliases[i].alias.first = addr->first;
    mail_aliases.aliases[i].alias.last = addr->last;
    mail_aliases.aliases[i].type = type;
}


void
#if HAVE_STDC
disp_alias(FILE *fp, int n, int verbose, int newline)
#else /* K&R style */
disp_alias(fp,n,verbose,newline)
FILE *fp;
int n;
int verbose;
int newline;
#endif /* HAVE_STDC */
{
    mail_alias *ma = &mail_aliases.aliases[n];
    if (verbose)
	fprintf(fp,"define %s ", ma->name);
    disp_addresses(fp, nil, &ma->alias, true, newline, false, false);
    if (!newline)			/* add trailing newline */
        fputc ('\n', fp);
}


addresslist *
#if HAVE_STDC
lookup_alias(const char *name)
#else /* K&R style */
lookup_alias(name)
const char *name;
#endif /* HAVE_STDC */
{
    mail_alias *ma;
    int i;

    if (mail_aliases.count == 0)
	return(nil);

    for(i = 0; i < mail_aliases.count; i++) {
	ma = &mail_aliases.aliases[i];
	if (ustrcmp(ma->name, name) == 0) {
	    return(&ma->alias);
	}
    }
    return(nil);
}
