#include <mysql/mysql.h>
#include "auto_break.h"
#include "control.h"
#include "fmt.h"
#include "mysql_queries.h"
#include "qsutil.h"
#include "subfd.h"
#include "substdio.h"
#include "stralloc.h"

extern int connect_mysql();

extern MYSQL dbh, *mysql;
extern MYSQL_RES *result;
extern stralloc envnoathost;
extern char strnum3[FMT_ULONG];

extern int do_query(stralloc *query, MYSQL_ROW *row);

/* map a virtual domain to a user-ext stralloc */
int vdoms_mysql(char *addr, int len, stralloc *ret) {
  char *host;
  int at, num, rows;
  MYSQL_ROW row;
  stralloc qmail_mysql_query = { 0 };
  stralloc real_addr = { 0 };
  stralloc real_host = { 0 };

  /* stralloc we're passed is unterminated */
  addr[len] = '\0';
  DEBUG_SAY("vdoms_mysql: ");
  DEBUG_SAY(addr);
  DEBUG_SAY("\n");
  num = len;
  host = addr + len;
  while (*host != '@') {
    host--;
    num--;
    if (host == addr) break;
  }
  at = num;

  /* let's lose the @ we found */
  host++;
  if (! stralloc_ready(&real_addr, 2 * str_len(addr) + 1)) return -1;
  mysql_escape_string(real_addr.s, addr, at);
  if (! stralloc_ready(&real_host, 2 * str_len(host) + 1)) {
    stralloc_free(&real_addr);
    return -1;
  }
  mysql_escape_string(real_host.s, host, str_len(host));

#define ACK {\
  stralloc_free(&real_addr);\
  stralloc_free(&real_host);\
  stralloc_free(&qmail_mysql_query);\
  return -1;\
}
  if (! connect_mysql()) ACK

  len += real_addr.len + real_host.len + str_len(VIRTUAL) + 2;
  if (! stralloc_ready(&qmail_mysql_query, len)) ACK
  if (! stralloc_cats(&qmail_mysql_query, VIRTUAL1)) ACK
  if (! stralloc_cats(&qmail_mysql_query, real_addr.s)) ACK
  if (! stralloc_cats(&qmail_mysql_query, VIRTUAL2)) ACK
  if (! stralloc_cats(&qmail_mysql_query, real_host.s)) ACK
  if (! stralloc_cats(&qmail_mysql_query, VIRTUAL3)) ACK
  if (! stralloc_0(&qmail_mysql_query)) ACK

#ifndef O_NOT_LOG
  log3("query: ", qmail_mysql_query.s, ";\n");
#endif
  rows = do_query(&qmail_mysql_query, &row);

  /* no row doesn't mean an error */
  if (rows < 1) {
    stralloc_free(&real_addr);
    stralloc_free(&real_host);
    return rows;
  }

  /* run database sanity check: username may not be blank */
  if (! *(row[0])) {
    log3("MySQL misconfiguration: username for host '", real_host.s, "' is blank in virtual table!\n");
    stralloc_free(&real_addr);
    stralloc_free(&real_host);
    mysql_free_result(result);
    return 0;
  }

#define YOW {\
  stralloc_free(&real_addr);\
  stralloc_free(&real_host);\
  mysql_free_result(result);\
  return -1;\
}
#ifdef MAGIC_FORWARDING
  if (! str_diff(row[0], MAGIC_FORWARD_USER)) {
    if (! stralloc_cats(ret, row[1])) YOW
    if (! stralloc_0(ret)) YOW
    mysql_free_result(result);
    stralloc_free(&real_addr);
    stralloc_free(&real_host);
#ifdef MAGIC_LOGGING
    log2("magic forward: msg ", strnum3);
    log2(" for ", addr);
    log3(" to ", row[1], "\n");
#endif
    return 2;
  }
#endif
  if (! stralloc_cats(ret, row[0])) YOW  /* username */
  if (str_len(row[1])) {
    if (! stralloc_append(ret, auto_break)) YOW
    if (*row[1] != '@') { if (! stralloc_cats(ret, row[1])) YOW }
    else if (! stralloc_cats(ret, real_addr.s)) YOW  /* ext */
  }
  if (! stralloc_append(ret, "@")) YOW
  if (! stralloc_cats(ret, real_host.s)) YOW
  if (! stralloc_0(ret)) YOW
  mysql_free_result(result);
  stralloc_free(&real_addr);
  stralloc_free(&real_host);
  return 1;
}


syntax highlighted by Code2HTML, v. 0.9.1