/*************************************************
*     Exim - an Internet mail transport agent    *
*************************************************/

/* Copyright (c) University of Cambridge 1995 - 2002 */
/* See the file NOTICE for conditions of use and distribution. */

#include "../exim.h"
#include "rf_functions.h"


/*************************************************
*        Queue address for transport             *
*************************************************/

/* This function is called to put an address onto the local or remote transport
queue, as appropriate. When the driver is for verifying only, a transport need
not be set, in which case it doesn't actually matter which queue the address
gets put on.

The generic uid/gid options are inspected and put into the address if they are
set. For a remote transport, if there are fallback hosts, they are added to the
address.

Arguments:
  addr          the address, with the transport field set (if not verify only)
  paddr_local   pointer to the anchor of the local transport chain
  paddr_remote  pointer to the anchor of the remote transport chain
  rblock        the router block
  pw            password entry if check_local_user was set, or NULL

Returns:        FALSE on error; the only case is failing to get a uid/gid
*/

BOOL
rf_queue_add(address_item *addr, address_item **paddr_local,
  address_item **paddr_remote, router_instance *rblock, struct passwd *pw)
{
addr->domain_data = deliver_domain_data;         /* Save these values for use */
addr->localpart_data = deliver_localpart_data;   /* in the transport */

/* Handle a local transport */

if (addr->transport != NULL && addr->transport->info->local)
  {
  ugid_block ugid;

  /* Default uid/gid and transport-time home directory are from the passwd file
  when check_local_user is set, but can be overridden by explicit settings.
  When getting the home directory out of the password information, wrap it
  in \N...\N to avoid expansion later. In Cygwin, home directories can
  contain $ characters. */

  if (pw != NULL)
    {
    addr->uid = pw->pw_uid;
    addr->gid = pw->pw_gid;
    setflag(addr, af_uid_set|af_gid_set);
    addr->home_dir = string_sprintf("\\N%s\\N", pw->pw_dir);
    }

  if (!rf_get_ugid(rblock, addr, &ugid)) return FALSE;
  rf_set_ugid(addr, &ugid);

  if (rblock->home_directory != NULL)
    addr->home_dir = rblock->home_directory;
  else if (addr->home_dir == NULL)
    addr->home_dir = rblock->router_home_directory;

  addr->current_dir = rblock->current_directory;

  addr->next = *paddr_local;
  *paddr_local = addr;
  }

/* For a remote transport, set up the fallback host list, and keep a count of
the total number of addresses routed to remote transports. */

else
  {
  addr->fallback_hosts = rblock->fallback_hostlist;
  addr->next = *paddr_remote;
  *paddr_remote = addr;
  remote_delivery_count++;
  }

DEBUG(D_route)
  {
  debug_printf("queued for %s transport: local_part = %s\ndomain = %s\n"
    "  errors_to=%s\n",
    (addr->transport == NULL)? US"<unset>" : addr->transport->name,
    addr->local_part, addr->domain, addr->p.errors_address);
  debug_printf("  domain_data=%s localpart_data=%s\n", addr->domain_data,
    addr->localpart_data);
  }

return TRUE;
}

/* End of rf_queue_add.c */
