#ident "@(#)librfc2822: :write_addr.c,v 1.1 2004/08/09 06:13:05 woods Exp "

/*
 * format a list of addresses back into a canonical textual representation.
 */

/*
 * Copyright (c) 2004	Greg A. Woods <woods@planix.com>
 */

#include <sys/cdefs.h>

#include <assert.h>
#include <stdio.h>
#include <string.h>

#include "rfc2822.h"
#include "librfc2822.h"

void
rfc2822_dump_addr_list(ofp, addr)
	FILE                   *ofp;
	rfc2822_mbxlst_t       *addr;
{
	rfc2822_mbxlst_t       *cur;

	for (cur = addr; cur; cur = cur->mbx_next) {
		rfc2822_dump_addr(ofp, cur);
	}

	return;
}

void
rfc2822_dump_addr(ofp, addr)
	FILE                   *ofp;
	rfc2822_mbxlst_t       *addr;
{
	if (addr->mbx_grp_list) {
		rfc2822_dump_mbox_list(ofp, addr->mbx_grp_list, addr->mbx_group);
	} else {
		fprintf(ofp, "addr_personal = '%s':\n", addr->mbx_personal);
		fprintf(ofp, "     mailbox = '%s',\n", addr->mbx_mailbox);
		fprintf(ofp, "     route = '%s',\n", addr->mbx_route);
		fprintf(ofp, "     domain = '%s'\n", addr->mbx_domain);
	}

	return;
}

void
rfc2822_dump_mbox_list(ofp, mbox, group_nm)
	FILE                   *ofp;
	rfc2822_mbxlst_t       *mbox;
	char                   *group_nm;
{
	rfc2822_mbxlst_t       *cur;

	fprintf(ofp, "group_name = '%s':\n", group_nm);
	for (cur = mbox; cur; cur = cur->mbx_next) {
		rfc2822_dump_mbox(ofp, cur);
	}

	return;
}

void
rfc2822_dump_mbox(ofp, mbox)
	FILE                   *ofp;
	rfc2822_mbxlst_t       *mbox;
{
	assert(! mbox->mbx_grp_list);

	fprintf(ofp, "     mbox_personal = '%s':\n", mbox->mbx_personal);
	fprintf(ofp, "          mailbox = '%s',\n", mbox->mbx_mailbox);
	fprintf(ofp, "          route = '%s',\n", mbox->mbx_route);
	fprintf(ofp, "          domain = '%s'\n", mbox->mbx_domain);

	return;
}


char *
rfc2822_fmt_addr_list(buf, buflen, addr)
	char                   *buf;
	size_t                  buflen;
	rfc2822_mbxlst_t       *addr;
{
	rfc2822_mbxlst_t       *cur;
	char                   *pbuf = buf;
	char                   *npbuf;

	for (cur = addr; cur; cur = cur->mbx_next) {
		npbuf = rfc2822_fmt_addr(pbuf, buflen, cur);
		buflen -= npbuf - pbuf;
		pbuf = npbuf;
	}

	return buf;
}

char *
rfc2822_fmt_addr(buf, buflen, addr)
	char                   *buf;
	size_t                  buflen;
	rfc2822_mbxlst_t       *addr;
{
	char           *pbuf = buf;

	if (!addr) {
		STRFCPY(pbuf, "(empty)", buflen);
		return NULL;
	}

	if (addr->mbx_grp_list) {
		return rfc2822_fmt_mbox_list(buf, buflen, addr->mbx_grp_list, addr->mbx_group);
	} else {
		size_t                  len;

		buflen--;		/* save room for the terminal nul */

		STRFCPY(pbuf, "(fmt_addr not yet implemented)", buflen);
		len = strlen(pbuf);
		pbuf += len;
		buflen -= len;
		
		/*
		 * no need to check for room for the NUL here since we already
		 * save space at the beginning of this routine
		 */
		*pbuf = '\0';
	}

	return buf;
}

char *
rfc2822_fmt_mbox_list(buf, buflen, mbox, group_nm)
	char                   *buf;
	size_t                  buflen;
	rfc2822_mbxlst_t       *mbox;
	char                   *group_nm;
{
	rfc2822_mbxlst_t       *cur;
	char                   *pbuf = buf;
	size_t                  len;
	char                   *npbuf;

	STRFCPY(pbuf, group_nm, buflen);
	len = strlen(pbuf);
	pbuf += len;
	buflen -= len;

	for (cur = mbox; cur; cur = cur->mbx_next) {
		npbuf = rfc2822_fmt_mbox(pbuf, buflen, cur);
		buflen -= npbuf - pbuf;
		pbuf = npbuf;
	}

	return buf;
}


char *
rfc2822_fmt_mbox(buf, buflen, mbox)
	char                   *buf;
	size_t                  buflen;
	rfc2822_mbxlst_t       *mbox;
{
	char                   *pbuf = buf;
	size_t                  len;

	if (!mbox) {
		STRFCPY(pbuf, "(empty)", buflen);
		return NULL;
	}

	buflen--;		/* save room for the terminal NUL */

	STRFCPY(pbuf, "(fmt_mbox not yet implemented)", buflen);
	len = strlen(pbuf);
	pbuf += len;
	buflen -= len;
		
	/*
	 * no need to check for room for the NUL here since we already
	 * save space at the beginning of this routine
	 */
	*pbuf = '\0';

	return buf;
}
