#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