#include "cdb.h"
#include "byte.h"
#include "open.h"
#include "error.h"
#include "control.h"
#include "constmap.h"
#include "stralloc.h"
#include "recipients.h"
#include "strerr.h"
#include "exit.h"

#define VERP
#define AUTO_BREAK '-'
#define WILDDOMAIN

static stralloc key = {0};
static stralloc domain = {0};
static stralloc wilddomain = {0};
static stralloc recipient = {0};
static int flagrcpts = 0;
static stralloc rcpts = {0};
static int fdrcps;

/* return -2: out of memory */
/* return -1: no control file */
/* return  0: address not found; fatal */
/* return  1: address in recipients */
/* return  2: VERP address */
/* return  3: wildcarded domain */
/* return  100: no recipients file */

int recipients_init()
{
  flagrcpts = control_readfile(&rcpts,"control/recipients",0);
  if (flagrcpts !=1) return flagrcpts;
}

int recipients(buf,len)
char *buf;
int len;
{
  int at;
  int ab;
  int i;

  if (flagrcpts != 1) return 100;

  if (!stralloc_copys(&recipient,"")) return -2;
  if (!stralloc_copys(&domain,"")) return -2;

  at = byte_rchr(buf,len,'@');
  if (at < len) {
    if (!stralloc_copyb(&domain,buf + at + 1,len - at - 1)) return -2;
    if (!stralloc_copyb(&recipient,buf,len)) return -2;
  } else {
    if (!stralloc_copyb(&recipient,buf,len)) return -2;
    if (!stralloc_append(&recipient,"@")) return -2;
    if (!stralloc_copys(&domain,"localhost")) return -2;
    if (!stralloc_cat(&recipient,&domain)) return -2; 
  }

  if (!stralloc_copys(&key,":")) return -2;
  if (!stralloc_cat(&key,&recipient)) return -2;
  if (!stralloc_0(&key)) return -2;
  case_lowerb(key.s,key.len);

  if (recipients_parse(rcpts.s,key.s) == 1) return 1;

#ifdef VERP
  for (i = 0; i < at; i++) {
    ab = 0;
    if (buf[i] == AUTO_BREAK) 
      ab = i;
    if (ab) {
      if (!stralloc_copys(&key,"")) return -2;
      if (!stralloc_copyb(&recipient,buf,ab)) return -2;
      if (!stralloc_append(&recipient,"@")) return -2;
      if (!stralloc_cat(&recipient,&domain)) return -2;
      if (!stralloc_copys(&key,":")) return -2;
      if (!stralloc_cat(&key,&recipient)) return -2;
      if (!stralloc_0(&key)) return -2;
      case_lowerb(key.s,key.len);

      if (recipients_parse(rcpts.s,key.s) == 1) return 2;
    }
  }
#endif

#ifdef WILDDOMAIN
  if (!stralloc_copys(&wilddomain,"!@")) return -2;
  if (!stralloc_cat(&wilddomain,&domain)) return -2; 
  if (!stralloc_copys(&key,":")) return -2;
  if (!stralloc_cat(&key,&wilddomain)) return -2;
  if (!stralloc_0(&key)) return -2;
  case_lowerb(key.s,key.len);

  if (recipients_parse(rcpts.s,key.s) == 1) return 3;
#endif

  return 0;
} 

int recipients_parse (rcps,rkey)
char *rcps;
char *rkey;
{
  for (;;) {         
    fdrcps = open_read(rcps);
    if (fdrcps != -1) {
      uint32 dlen;
      int r;
      r = cdb_seek(fdrcps,rkey,str_len(rkey),&dlen);
      close(fdrcps);
      if (r) return 1;
    }
    rcps = rcps + str_len(rcps) + 1;
    if (*rcps == 'Z' || *rcps == ' ') return 0;
  }
  return 0;
}


syntax highlighted by Code2HTML, v. 0.9.1