/* $NetBSD: recipient_list.c,v 1.2 2017/02/14 01:16:45 christos Exp $ */
/*++
/* NAME
/* recipient_list 3
/* SUMMARY
/* in-core recipient structures
/* SYNOPSIS
/* #include <recipient_list.h>
/*
/* typedef struct {
/* .in +4
/* long offset;
/* char *dsn_orcpt;
/* int dsn_notify;
/* char *orig_addr;
/* char *address;
/* union {
/* .in +4
/* int status;
/* struct QMGR_QUEUE *queue;
/* char *addr_type;
/* .in -4
/* }
/* .in -4
/* } RECIPIENT;
/*
/* typedef struct {
/* .in +4
/* RECIPIENT *info;
/* private members...
/* .in -4
/* } RECIPIENT_LIST;
/*
/* void recipient_list_init(list, variant)
/* RECIPIENT_LIST *list;
/* int variant;
/*
/* void recipient_list_add(list, offset, dsn_orcpt, dsn_notify,
/* orig_rcpt, recipient)
/* RECIPIENT_LIST *list;
/* long offset;
/* const char *dsn_orcpt;
/* int dsn_notify;
/* const char *orig_rcpt;
/* const char *recipient;
/*
/* void recipient_list_swap(a, b)
/* RECIPIENT_LIST *a;
/* RECIPIENT_LIST *b;
/*
/* void recipient_list_free(list)
/* RECIPIENT_LIST *list;
/*
/* void RECIPIENT_ASSIGN(rcpt, offset, dsn_orcpt, dsn_notify,
/* orig_rcpt, recipient)
/* RECIPIENT *rcpt;
/* long offset;
/* char *dsn_orcpt;
/* int dsn_notify;
/* char *orig_rcpt;
/* char *recipient;
/* DESCRIPTION
/* This module maintains lists of recipient structures. Each
/* recipient is characterized by a destination address and
/* by the queue file offset of its delivery status record.
/* The per-recipient status is initialized to zero, and exists
/* solely for the convenience of the application. It is not used
/* by the recipient_list module itself.
/*
/* recipient_list_init() creates an empty recipient structure list.
/* The list argument is initialized such that it can be given to
/* recipient_list_add() and to recipient_list_free(). The variant
/* argument specifies how list elements should be initialized;
/* specify RCPT_LIST_INIT_STATUS to zero the status field, and
/* RCPT_LIST_INIT_QUEUE to zero the queue field.
/*
/* recipient_list_add() adds a recipient to the specified list.
/* Recipient address information is copied with mystrdup().
/*
/* recipient_list_swap() swaps the recipients between
/* the given two recipient lists.
/*
/* recipient_list_free() releases memory for the specified list
/* of recipient structures.
/*
/* RECIPIENT_ASSIGN() assigns the fields of a recipient structure
/* without making copies of its arguments.
/*
/* Arguments:
/* .IP list
/* Recipient list initialized by recipient_list_init().
/* .IP offset
/* Queue file offset of a recipient delivery status record.
/* .IP dsn_orcpt
/* DSN original recipient.
/* .IP notify
/* DSN notify flags.
/* .IP recipient
/* Recipient destination address.
/* SEE ALSO
/* recipient_list(3h) data structure
/* DIAGNOSTICS
/* Fatal errors: memory allocation.
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/
/* System library. */
#include <sys_defs.h>
/* Utility library. */
#include <mymalloc.h>
#include <msg.h>
/* Global library. */
#include "recipient_list.h"
/* recipient_list_init - initialize */
void recipient_list_init(RECIPIENT_LIST *list, int variant)
{
list->avail = 1;
list->len = 0;
list->info = (RECIPIENT *) mymalloc(sizeof(RECIPIENT));
list->variant = variant;
}
/* recipient_list_add - add rcpt to list */
void recipient_list_add(RECIPIENT_LIST *list, long offset,
const char *dsn_orcpt, int dsn_notify,
const char *orig_rcpt, const char *rcpt)
{
int new_avail;
if (list->len >= list->avail) {
new_avail = list->avail * 2;
list->info = (RECIPIENT *)
myrealloc((void *) list->info, new_avail * sizeof(RECIPIENT));
list->avail = new_avail;
}
list->info[list->len].orig_addr = mystrdup(orig_rcpt);
list->info[list->len].address = mystrdup(rcpt);
list->info[list->len].offset = offset;
list->info[list->len].dsn_orcpt = mystrdup(dsn_orcpt);
list->info[list->len].dsn_notify = dsn_notify;
if (list->variant == RCPT_LIST_INIT_STATUS)
list->info[list->len].u.status = 0;
else if (list->variant == RCPT_LIST_INIT_QUEUE)
list->info[list->len].u.queue = 0;
else if (list->variant == RCPT_LIST_INIT_ADDR)
list->info[list->len].u.addr_type = 0;
list->len++;
}
/* recipient_list_swap - swap recipients between the two recipient lists */
void recipient_list_swap(RECIPIENT_LIST *a, RECIPIENT_LIST *b)
{
if (b->variant != a->variant)
msg_panic("recipient_lists_swap: incompatible recipient list variants");
#define SWAP(t, x) do { t x = b->x; b->x = a->x ; a->x = x; } while (0)
SWAP(RECIPIENT *, info);
SWAP(int, len);
SWAP(int, avail);
}
/* recipient_list_free - release memory for in-core recipient structure */
void recipient_list_free(RECIPIENT_LIST *list)
{
RECIPIENT *rcpt;
for (rcpt = list->info; rcpt < list->info + list->len; rcpt++) {
myfree((void *) rcpt->dsn_orcpt);
myfree((void *) rcpt->orig_addr);
myfree((void *) rcpt->address);
}
myfree((void *) list->info);
}