/******************************************************************
 * PTlink Services is (C) CopyRight PTlink IRC Software 1999-2005 *
 *                http://software.pt-link.net                     *
 * This program is distributed under GNU Public License           *
 * Please read the file COPYING for copyright information.        *
 ******************************************************************
                                                                                
  File: ns_last.c
  Description: nickserv last/slast command
                                                                                
 *  $Id: ns_last.c,v 1.6 2005/10/18 16:25:06 jpinto Exp $
*/

#include "module.h"
#include "dbconf.h"
#include "nsmacros.h"
#include "my_sql.h"
#include "ns_group.h"
/* lang files */
#include "lang/common.lh"
#include "lang/ns_last.lh"

SVS_Module mod_info =
/* module, version, description */
{ "ns_last", "1.0","nickserv last/slast command" };

/* Change Log
  1.0 -  #2 : ns_last module to record/display nicks login activity
*/

#define DB_VERSION 1

/* external functions/events we require */
ServiceUser* (*nickserv_suser)(void);
u_int32_t (*find_group)(char *name);
static int e_nick_identify;
static int e_nick_register;
MOD_REQUIRES
  DBCONF_FUNCTIONS
  MOD_FUNC(nickserv_suser)
  MOD_FUNC(is_sadmin)
  MOD_FUNC(find_group)  
  MOD_FUNC(e_nick_identify)
  MOD_FUNC(e_nick_register)
MOD_END

static int ExpireTime;

/* configuration items we provide */
DBCONF_PROVIDES
  DBCONF_TIME(ExpireTime, "1M", 
    "How long information from last logins will be kept ?\n"
    "Please note that old logins info is only deleted during nick logins")
DBCONF_END

/* internal functions */
int ev_ns_last_nick_identify(IRC_User* u, u_int32_t* snid);

/* available commands from module */

void ns_last(IRC_User *s, IRC_User *u);
void ns_slast(IRC_User *s, IRC_User *u);

/* Local settings */

/* Local vars */
ServiceUser* nsu;
int ns_log;

int mod_rehash(void)
{
  if(dbconf_get_or_build(mod_info.name, dbconf_provides) < 0 )
  {
    errlog("Error reading dbconf!");
    return -1;
  }
  return 0;
}

int mod_load(void)
{
  int r = sql_check_inst_upgrade(mod_info.name, DB_VERSION, NULL);  
  if(r < 0)
    return -1;  
  ns_log = log_handle("nickserv");
  nsu = nickserv_suser();  
  /* add commands */
  suser_add_cmd(nsu, "LAST", ns_last, NS_LAST_SUMMARY, NS_LAST_HELP);
  suser_add_cmd_g(nsu, "SLAST", ns_slast, NS_SLAST_SUMMARY, NS_SLAST_HELP,
    find_group("Admin"));
        
  /* add events */
  mod_add_event_action(e_nick_identify, 
    (ActionHandler) ev_ns_last_nick_identify);
  mod_add_event_action(e_nick_register, 
    (ActionHandler) ev_ns_last_nick_identify);
  return 0;
}

void mod_unload(void)
{
  suser_del_mod_cmds(nsu, &mod_info);     
}

/* s = service the command was sent to
   u = user the command was sent from */
void ns_last(IRC_User *s, IRC_User *u)
{
  MYSQL_RES *res;
  MYSQL_ROW row;
  u_int32_t source_snid;

  CHECK_IF_IDENTIFIED_NICK
  
  send_lang(u, s, NS_LAST_HEADER);
  res = sql_query("SELECT t_when, username, realhost, realname, web "
    "FROM ns_last WHERE snid=%d ORDER BY t_when DESC", source_snid);
  while((row = sql_next_row(res)))
  {
    char buf[64];
    char buf2[128];
    struct tm *tm;
    time_t t_when = atoi(row[0]);
    tm = localtime(&t_when);    
    strftime(buf, sizeof(buf), format_str(u, DATE_FORMAT), tm);
    if(row[1] && row[2])
      snprintf(buf2, sizeof(buf2), "%s@%s", row[1], row[2]);
    else if(row[2])
      snprintf(buf2, sizeof(buf2), "%s", row[2]);
    else
      buf2[0] = '\0';
    if(row[4] && (*row[4] == 'y'))
      strcat(buf2, " (Web)");
    send_lang(u, s, NS_LAST_ITEM_X_X_X,
      buf, buf2, row[3] ? row[3] : "");
  }
  send_lang(u, s, NS_LAST_TAIL);
  
  sql_free(res);  
}

/* s = service the command was sent to
   u = user the command was sent from */
void ns_slast(IRC_User *s, IRC_User *u)
{
  MYSQL_RES *res;
  MYSQL_ROW row;
  u_int32_t source_snid;
  char *nick;

  CHECK_IF_IDENTIFIED_NICK

  if(!is_sadmin(source_snid))
    send_lang(u, s, ONLY_FOR_SADMINS);  
  else
  if((nick = strtok(NULL, " ")) == NULL)
    send_lang(u,s, NS_SLAST_SYNTAX);
  else 
  if(sql_singlequery("SELECT snid FROM nickserv WHERE nick=%s",
    sql_str(irc_lower_nick(nick))) == 0)
      send_lang(u, s, NICK_X_NOT_REGISTERED, nick);
  else
  {   
    u_int32_t snid = sql_field_i(0);
    send_lang(u, s, NS_LAST_HEADER_X, nick);
    res = sql_query("SELECT t_when, username, realhost, realname, web "
      "FROM ns_last WHERE snid=%d ORDER BY t_when", snid);
    while((row = sql_next_row(res)))
    {
      char buf[64];
      char buf2[128];
      struct tm *tm;
      time_t t_when = atoi(row[0]);
      tm = localtime(&t_when);    
      strftime(buf, sizeof(buf), format_str(u, DATE_FORMAT), tm);
      if(row[1] && row[2])
        snprintf(buf2, sizeof(buf2), "%s@%s", row[1], row[2]);
      else 
      if(row[2])
        snprintf(buf2, sizeof(buf2), "%s", row[2]);
      else
        buf2[0] = '\0';
      if(row[4] && (*row[4] == 'y'))
      strcat(buf2, "Web");
      send_lang(u, s, NS_LAST_ITEM_X_X_X,
      buf, buf2, row[3] ? row[3] : "");
    }
    send_lang(u, s, NS_LAST_TAIL);
    sql_free(res);      
  }
}

/* nick has identified, record nick info */
int ev_ns_last_nick_identify(IRC_User* u, u_int32_t* snid)
{
  /* first lets delete the old login info */
  sql_execute("DELETE FROM ns_last WHERE snid=%d AND t_when < %d",
    *snid, irc_CurrentTime - ExpireTime);
  sqlb_init("ns_last");
  sqlb_add_int("snid", *snid);
  sqlb_add_str("web", "n");
  sqlb_add_int("t_when", (int) irc_CurrentTime);
  sqlb_add_str("username", u->username);
  sqlb_add_str("publichost", u->publichost);
  sqlb_add_str("realhost", u->realhost);
  sqlb_add_str("realname", u->info);      
  return sql_execute("%s", sqlb_insert());
}


syntax highlighted by Code2HTML, v. 0.9.1