/*
 * block.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"

#define MIN(x, y) (((x) < (y)) ? (x) : (y))

void m_block(char *a);

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

  snprintf(dl->help, MAX_COMMAND_HELP_LEN,
	   "/msg %s BLOCK <nick> [duration (h/d/w/m/y)>] [reason]\nAdd a G-line to a user, and refuse connections for some time.\n"
	   , BOT_NAME);
  snprintf(dl->summary, MAX_COMMAND_SUMMARY_LEN,
	   "Add a G-line to a user");
  dl->level = 950;
#if 0
  dl->func = m_block;
#else
  dl->func = (void (*)(char*)) DL_sym(dl->val, "m_block");
#endif
  return 1;
}

MODULE_PUBLIC int _remove_block(char *a, char *b)
{
  remove_command("block");
  return 1;
}

MODULE_PUBLIC void m_block(char *a)
{
  struct activeuser *u;
  ListElem *el;
  struct gline *g;
  char tmp[512];
  char time_str[80];
  int start;
  int i, nr;
  char gline[GLINELEN+1];
  char gline_mask[GLINELEN+1];
  char nick[NICKLEN+1];
  char user[USERLEN+1];
  char host[HOSTLEN+1];
  int dur_len;
  int rlen;
  long durationl;
  char duration[REASONLEN+1];
  char reason_test[REASONLEN+1];
  char reason[REASONLEN+1];
  struct tm *tm_;
  time_t time_;
  struct dbaseuser *db;
  db = sender_au->dbuser;
  if(db) {
    log("From: %s block [%s]\n", db->nick, a);
  } else
    return;
  if(!is_oper()) {
    say_sender("You are not an Oper.");
    log("To: %s Is not an Oper\n", db->nick);
    return;
  }

  i=0;
  strncpy(nick, getword(a,&i), NICKLEN);
  nick[NICKLEN] = '\0';

  if(strlen(nick) < 1) {
    say_sender( "You forgot to specify a nickname");
    say_sender_( "/msg %s BLOCK nickname <nick> [duration (h/d/w/m/y)] [reason]", BOT_NAME);
    return;
  }

  u = findauser(nick);
  if(!u) {
    say_sender("Couldn't find that user");
    return;
  }

  strcpy(user, "*");
  strncpy(host, u->hostname, HOSTLEN);
  host[HOSTLEN] = '\0';
  strcpy(nick, "*");

  /* convert it to correct format ! */
  strncpy(gline_mask, banstylename(nick, user, host), GLINELEN);
  gline_mask[GLINELEN] = '\0';

  if(!strcmp(gline_mask, "*@*")) {
    say_sender("G-line shouldn't be *@*");
    return;
  }
  if(!strcmp(user, "*") && !strcmp(host, "*")) {
    say_sender("G-line shouldn't be *@*");
    return;
  }

  if(strlen(gline_mask) < 5) {
    say_sender("G-line too short");
    return;
  }

  strncpy(gline, &gline_mask[2], GLINELEN-2);
  gline[GLINELEN-2] = '\0';

  start = i+1;
  strncpy(duration, getword(a,&i), REASONLEN);
  duration[REASONLEN] = '\0';
  if(strlen(duration)) {
    if(isdigit(duration[0])) {

      durationl = atol(duration);
      dur_len = strlen(duration);
      
      if(dur_len && !isdigit(duration[dur_len-1])) {
	switch(duration[dur_len-1]) {
	case 'h':
	  durationl *= 3600;
	  break;
	case 'd':
	  durationl *= 24*3600;
	  break;
	case 'w':
	  durationl *= 7*24*3600;
	  break;
	case 'm':
	  durationl *= 30*24*3600;
	  break;
	case 'y':
	  durationl *= 365*24*3600;
	  break;
	default:
	  break;
	}
      }
      if(durationl == 0) {
	say_sender("No duration length was given.");
	return;
      }

      start = i+1;
      strncpy(reason_test, getword(a,&i), 10);
      reason_test[10] = '\0';
      if(!strlen(reason_test)) {
	say_sender("No reason was given.");
	return;
      }
      strncpy(reason, &a[start], REASONLEN);
      rlen = MIN(strlen(&a[start]), REASONLEN);
      reason[rlen] = '\0';

    } else {
      durationl = 3600;
      strncpy(reason, &a[start], REASONLEN);
      rlen = MIN(strlen(&a[start]), REASONLEN);
      reason[rlen] = '\0';
    }
  } else {
    /* there are no more parameters */
    durationl = 3600;
    sprintf(reason, "Network Trouble Maker");
  }

  sprintf(duration, "%lu", durationl);
  g = gline_add(gline, duration, reason, sender_au->userid, 0);
  if(!g) {
    say_sender("Couldn't add the G-line for some reason.");
    return;
  }
  strncpy(g->user, user, USERLEN);
  g->user[USERLEN] = '\0';
  strncpy(g->host, host, HOSTLEN);
  g->host[HOSTLEN] = '\0';

  nr = 0;
  el = GetHead(auser_list);
  while(el) {
    u = (struct activeuser *)el->data;
    if(matches_gline(u, g)) {
      nr++;
    }
    el = GetSucc(el);
  }
  if((nr > 40) && (nr > servers[MAX_SERVERS].users/10)) {
    sprintf(tmp, "You are not allowed to G-line %d users", nr);
    say_sender(tmp);
    gline_del(g->gline);
    return;
  }

  time_ = durationl + time(NULL);
  tm_ = localtime(&time_);
  strftime(time_str, 60, "%c", tm_);
  sprintf(tmp, "GLINE %s expires %s (%d user%s) (set by %s)\n", gline, time_str,
	  nr, ((nr==1) ? "" : "s"), sender_au->dbuser->nick);
  wallop(tmp);
  log(tmp);

  putserver("%c%c GL * +%s %ld :%s\n\r", yxx[0], yxx[1], g->gline, g->duration, g->reason);
  return;
}
