#include "constmap.h"
#include "control.h"
#include "str.h"
#include "stralloc.h"
#include "substdio.h"
#include "subfd.h"
#include "mysql_queries.h"

extern int connect_mysql();
extern void disconnect_mysql();
extern int vdoms_mysql();
extern int checkuser_mysql();

extern char auto_qmail[];

stralloc envnoathost = { 0 };
stralloc locals = { 0 };
stralloc percenthack = { 0 };
stralloc qmail_mysql_query = { 0 };
struct constmap maplocals;
struct constmap mappercenthack;
char *strnum3 = "test";

int main(int argc, char **argv) {
  int at, i, j, local;
  stralloc addr = { 0 };
  stralloc ret = { 0 };
  
  if (argc == 1) {
    substdio_putsflush(subfdout, "addrexp: expand a virtual address\n");
    substdio_putsflush(subfdout, "usage: addrexp virtual_username@virtual_host\n");
    substdio_putsflush(subfdout, "returns: final delivery address for virtual_username@virtual_host\n");
    substdio_putsflush(subfdout, "exit codes:   0 if the address is local\n");
    substdio_putsflush(subfdout, "              1 if the address is a virtual domain\n");
    substdio_putsflush(subfdout, "              2 if the address is remote\n");
    substdio_putsflush(subfdout, "            100 if there was an error reading controls\n");
    substdio_putsflush(subfdout, "            111 if there was a database error\n");
    _exit(1);
  }

  if (chdir(auto_qmail) == -1) _exit(100);
  if (control_init() == -1) _exit(100);
  if (control_rldef(&envnoathost, "control/envnoathost", 1, "envnoathost") == -1) _exit(100);
  if (control_readfile(&locals,"control/locals",1) != 1) _exit(100);
  if (!constmap_init(&maplocals,locals.s,locals.len,0)) _exit(100);
  switch(control_readfile(&percenthack,"control/percenthack",0)) {
    case -1: return 0;
    case 0: if (!constmap_init(&mappercenthack,"",0,0)) return 0; break;
    case 1: if (!constmap_init(&mappercenthack,percenthack.s,percenthack.len,0)) return 0; break;
  }
  if (! stralloc_ready(&addr, str_len(argv[1]) + 1)) _exit(100);
  if (! stralloc_cats(&addr, argv[1])) _exit(100);

  /* some of this ripped from qmail-send */
  i = byte_rchr(addr.s, addr.len, '@');
  if (i == addr.len) {
    if (! stralloc_readyplus(&addr, envnoathost.len + 1)) _exit(100);
    if (! stralloc_append(&addr, "@")) _exit(100);
    if (! stralloc_cat(&addr, &envnoathost)) _exit(100);
  }

  while (constmap(&mappercenthack,addr.s + i + 1,addr.len - i - 1)) {
    j = byte_rchr(addr.s,i,'%');
    if (j == i) break;
    addr.len = i;
    i = j;
    addr.s[i] = '@';
  }

  at = byte_rchr(addr.s,addr.len,'@');

  if (! connect_mysql()) _exit(111);
  local = 2;
  i = 0;
  if (constmap(&maplocals,addr.s + at + 1,addr.len - at - 1)) {
    local = 1; /* maybe one day expand to alias etc */
/*printf("checkuser_mysql(%s, %d) = ", addr.s, at);*/
    i = checkuser_mysql(addr.s, at);
/*printf("%d\n", i);*/
    if (i == -1) _exit(111);
    if (i) {
      if (!stralloc_cat(&ret,&addr)) _exit(100);
      if (!stralloc_0(&ret)) _exit(100);
      local = 0;
    }
    else {
      /* try virtual with the given host - then fall back to envnoathost */
/*printf("local vdoms_mysql(%s, %i, &ret) = ", addr.s, addr.len);*/
      i = vdoms_mysql(addr.s, addr.len, &ret);
/*printf("%d\n", i);*/
      if (i == -1) _exit(111);
      if (i) local = 0;
      else {
        addr.len = at + 1;
        if (! stralloc_cat(&addr, &envnoathost)) _exit(100);
      }
    }
  }

  if (! i) if (i = vdoms_mysql(addr.s, addr.len, &ret)) local = 1;
/*printf("%d\n", i);*/
  if (i == -1) _exit(111);
 
  if (i) substdio_puts(subfdout, ret.s);
  else substdio_puts(subfdout, argv[1]);
  substdio_putsflush(subfdout, "\n");
  disconnect_mysql();
  _exit(local);
}


syntax highlighted by Code2HTML, v. 0.9.1