#include <mysql/mysql.h>
#include "auto_qmail.h"
#include "readwrite.h"
#include "str.h"
#include "stralloc.h"
#include "substdio.h"
#include "subfd.h"

#define SQLSERVER "/control/sqlserver"

/* let's alloc our strallocs */
stralloc DB_HOST = { 0 };
stralloc DB_USER = { 0 };
stralloc DB_PASS = { 0 };
stralloc DB_NAME = { 0 };
stralloc DB_SOCK = { 0 };
stralloc DB_PORT = { 0 };

static char inbuf[64];
MYSQL dbh, *mysql;
MYSQL_RES *result;

/* read the config file and decide which server the database is on, what      */
/* username and password we need to connect to it and which database to use   */
/* return -1 if a bad error occurred, 0 if everything was OK or 1 if not      */
int init_mysql() {
  int i, error, file, match;
  substdio ss;
  stralloc filename = { 0 };
  stralloc buf = { 0 };
  
  if (mysql) return 1;
  mysql = mysql_init(&dbh);
  if (! mysql) return -1;

  /* get the filename of the sqlserver control file */
  i = str_len(SQLSERVER) + str_len(auto_qmail) + 1;
  if (! stralloc_ready(&filename, i)) return -1;
  if (! stralloc_cats(&filename, auto_qmail)) return -1;
  if (! stralloc_cats(&filename, SQLSERVER)) return -1;
  if (! stralloc_0(&filename)) return -1;
  
  /* try to open the file - much code robbed from control.c*/
  file = open_read(filename.s);
  if (file == -1) {
    substdio_puts(subfderr, "warning: could not open sqlserver file ");
    substdio_puts(subfderr, filename.s);
    substdio_putsflush(subfderr, "\n");
    return 0;
  }
  substdio_fdbuf(&ss, read, file, inbuf, sizeof(inbuf));
  
  i = 0;
  while (getln(&ss, &buf, &match, '\n') != -1) {
    if (! match && ! buf.len) break;
    buf.len--;
    if (! stralloc_0(&buf)) break;
    /* we consider only lines starting with the letters s,l,p or d */
    switch (buf.s[0]) {
      case 's':
        if (buf.s[1] == 'e') error = getconfig(&buf, "server", &DB_HOST);
        else error = getconfig(&buf, "socket", &DB_SOCK);
        break;
      case 'l': error = getconfig(&buf, "login", &DB_USER); break;
      case 'p':
        if (buf.s[1] == 'a') error = getconfig(&buf, "password", &DB_PASS);
        else error = getconfig(&buf, "port", &DB_PORT);
        break;
      case 'd': error = getconfig(&buf, "db", &DB_NAME); break;
      default: continue;
    }
    if (error == -1) {
      i = -1;
      continue;
    }
    else i += error;
    if (! match) break;
  }
  close(file);

  if (i == -1)
    substdio_putsflush(subfderr, "warning: there were errors reading sqlserver file\n");
  else if (i > 0) {
    substdio_putsflush(subfderr, "warning: bogus lines in sqlserver file\n");
    i = 0;
  }
  return i;
}

/* read lines in the config file and grok entries of the form "x=y" or "x y"  */
/* got is the line in the file, expected is the parmeter we're checking for   */
/* and store is a stralloc to put the result into if it was found             */
int getconfig(stralloc *got, char *expected, stralloc *store) {
  char *value, *x;

  x = got->s + str_len(expected);
  value = x + 1;
  /* we got a meaningful value */
  if (! stralloc_starts(&got, expected) && (*x == ' ' || *x == '=') && str_len(value) > 0) {
    if (! stralloc_ready(store, str_len(value))) return -1;
    if (! stralloc_cats(store, value)) return -1;
    if (! stralloc_0(store)) return -1;
    return 0;
  }
  /* oh dear, the line we got didn't contain what we expected it to */
  substdio_puts(subfderr, "error reading sqlserver file: expected '");
  substdio_puts(subfderr, expected);
  substdio_puts(subfderr, "' but got '");
  substdio_puts(subfderr, got);
  substdio_putsflush(subfderr, "'\n");
  /* of course, we might have been expecting the wrong thing... */
  return 1;
}


syntax highlighted by Code2HTML, v. 0.9.1