/*
 * auth.c
 * (C) Christian Magnusson 2000, Email: d1mag@dtek.chalmers.se
 * This program is copyright, and covered by the Gnu Public License.
 * The Q bot.
 */

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "settings.h"
#include "bottypes.h"
#include "globals.h"
#include "dl.h"

void m_auth(char *a);

int _init_auth(void *a, void *b)
{
  dl_command_entry_t *dl = a;
  if(!a) return 0;

  snprintf(dl->help, MAX_COMMAND_HELP_LEN,
           "/msg %s@%s AUTH <nick> <password>\nThis will identify you on the bot as <nick> until you next quit from IRC or are split from the bot.\n", BOT_NAME, BOT_HOSTNAME);
  snprintf(dl->summary, MAX_COMMAND_SUMMARY_LEN,
           "Identifies you as a particular user on the bot.");
  dl->level = 0;
#if 0
  dl->func = m_auth;
#else
  dl->func = (void (*)(char*)) DL_sym(dl->val, "m_auth");
#endif
  return 1;
}

int _remove_auth(char *a, char *b)
{
  remove_command("auth");
  return 1;
}


void m_auth(char *a)
{
  struct activeuser *u;
  ListElem *el;
  char tmp[HOSTLEN+NICKLEN+USERLEN+81];
  struct dbaseuser *d;
  struct chanmod *c, *cn;
  char name[NICKLEN+1];
  char password[PASSLEN+1];
  int err, i = 0;
  int len;

  if(!sender_au) return;

  strncpy(name,getword(a,&i),NICKLEN);
  name[NICKLEN] = '\0';
  if(!strlen(name)) {
    say_sender("You forgot to type your nick!");
    say_sender_("Type: /msg %s@%s AUTH nick password", BOT_NAME, BOT_HOSTNAME);
    return;
  }
  strncpy(password,getword(a,&i),PASSLEN);
  password[PASSLEN] = '\0';
  if(!strlen(password)) {
    say_sender("You forgot to type your password!");
    say_sender_("Type: /msg %s@%s AUTH nick password", BOT_NAME, BOT_HOSTNAME);
    return;
  }

  d = finduserfromname(name);
  if(!d) {
    say_sender("You have probably typed wrong nickname");
    sqlqlog(QLOG_BADAUTH,sender_au->nick,sender_au->username,sender_au->hostname,"%s %s","0",a);
  } else {
    if(dbasecheck(d, password)) {
#if 0
      if(sender_au->userid) {
        /*
          The user was authed before, and the userid will be changed.
          Could be a sign of repeating auth loop.
        */
        if(sender_au->userid != d->userid) {
          log("Warning: m_auth: user was already authed as [%d]\n", sender_au->userid);
        }
      }
#endif
     
      d->last_auth = time(NULL);
      sender_au->auth = d->globalauth;
      sender_au->userid = d->userid;

      /* this will warn opers if a user use many different accounts */
      add_userid_history(sender_au, sender_au->userid);

      sender_au->dbuser = d;   /* pointer to the database entry */
      
      if((d->globalauth > 1) || sender_au->oper) {
        log("From: m_auth: [%s] auth [%s!%s@%s] [%s] LEVEL=%d OPER=%d\n",
            sender_au->nick, sender_au->nick, sender_au->username, sender_au->hostname, a, d->globalauth, sender_au->oper);
      } else {
        log("From: m_auth: [%s] auth [%s!%s@%s] [%s]\n",
            sender_au->nick, sender_au->nick, sender_au->username, sender_au->hostname, a);
      }
      sqlqlog(QLOG_GOODAUTH,sender_au->nick,sender_au->username,sender_au->hostname,"%d %d %s %s",d->globalauth,sender_au->oper,d->nick,(d->globalauth<100) ? a : "hidden because authlev >= 100");

      strncpy(d->last_username, sender_au->username, USERLEN);
      d->last_username[USERLEN] = '\0';

      if(d->last_hostname) Free(d->last_hostname);
      len = MIN(strlen(sender_au->hostname), HOSTLEN);
      d->last_hostname = Malloc(len + 1);
      strncpy(d->last_hostname, sender_au->hostname, len);
      d->last_hostname[len] = '\0';
      /*
      strncpy(d->last_hostname, sender_au->hostname, HOSTLEN);
      d->last_hostname[HOSTLEN] = '\0';
      */
      strncpy(d->last_yxx, sender_au->yxx, YXXLEN);
      d->last_yxx[YXXLEN] = '\0';

      c = sender_au->chanmodes;
      while(c) {
        cn = c->next;
        /*
          handlejoin could actually kick the user from a channel
          if user has joined, THEN auth.
          Make sure c isn't a free'd pointer.
        */
        err = handlejoin_u(sender_au, c->channel, 1);
        if(err >= 0) {
          c = cn;
        } else if(err == -1) {
          /* the user was killed due to his channels joins */
          return;
        }
      }

      say_sender("AUTH'd successfully.");

      if(!d->email || !strlen(d->email)) {
        say_sender("MOTD: We have added a new feature to Q now. To prevent problems in case you forget your login/password, two new commands are added. (EMAIL, REQUESTPASSWORD) IRCOperators will NEVER send passwords to users anymore. If you have set your E-mail you can get the password by yourself, otherwise you have to re-create a new account.");
        say_sender_("/MSG %s HELP EMAIL    /MSG %s HELP REQUESTPASSWORD", BOT_NAME, BOT_NAME);
      }

      el = GetHead(auser_list);
      while(el) {
        u = (struct activeuser *)el->data;
        if(u->userid == sender_au->userid) {
          if(strcmp(u->yxx, sender_au->yxx)) {
            snprintf(tmp, HOSTLEN+NICKLEN+USERLEN+80,
                     "Warning: %s (%s@%s) authed with your password.",
                     sender_au->nick, sender_au->username, sender_au->hostname);
            say_y(u->yxx, tmp);
          }
        }
        el = GetSucc(el);
      }
      return;
    } else {
      say_sender("You have probably typed wrong password");
      log("From: m_auth: FAILED [%s] auth [%s!%s@%s] [%s]\n",
          sender_au->nick, sender_au->nick, sender_au->username, sender_au->hostname, a);
      sqlqlog(QLOG_BADAUTH,sender_au->nick,sender_au->username,sender_au->hostname,"%s %s","1",a);
    }
  }
  say_sender_("Type: /msg %s@%s AUTH nick password", BOT_NAME, BOT_HOSTNAME);
  return;
}
