home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / ircd4652.zip / ircd-df-4.6.5-os2 / src / whowas.c < prev    next >
C/C++ Source or Header  |  1997-12-28  |  6KB  |  261 lines

  1. /************************************************************************
  2.  *   IRC - Internet Relay Chat, ircd/whowas.c
  3.  *   Copyright (C) 1990 Markku Savela
  4.  *
  5.  *   This program is free software; you can redistribute it and/or modify
  6.  *   it under the terms of the GNU General Public License as published by
  7.  *   the Free Software Foundation; either version 1, or (at your option)
  8.  *   any later version.
  9.  *
  10.  *   This program is distributed in the hope that it will be useful,
  11.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *   GNU General Public License for more details.
  14.  *
  15.  *   You should have received a copy of the GNU General Public License
  16.  *   along with this program; if not, write to the Free Software
  17.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19.  
  20. /*
  21.  * --- avalon --- 6th April 1992
  22.  * rewritten to scrap linked lists and use a table of structures which
  23.  * is referenced like a circular loop. Should be faster and more efficient.
  24.  */
  25.  
  26. #ifndef lint
  27. static  char sccsid[] = "@(#)whowas.c    2.16 08 Nov 1993 (C) 1988 Markku Savela";
  28. #endif
  29.  
  30. #include "struct.h"
  31. #include "common.h"
  32. #include "sys.h"
  33. #include "numeric.h"
  34. #include "whowas.h"
  35. #include "h.h"
  36.  
  37. static    aName    was[NICKNAMEHISTORYLENGTH];
  38. static    int    ww_index = 0;
  39.  
  40. void    add_history(cptr)
  41. Reg1    aClient    *cptr;
  42. {
  43.     aName    ntmp;
  44.     Reg2    aName    *np = &ntmp, *np2;
  45.     Link    *lp;
  46.  
  47.     strncpyzt(np->ww_nick, cptr->name, NICKLEN+1);
  48.     strncpyzt(np->ww_info, cptr->info, REALLEN+1);
  49.     np->ww_user = cptr->user;
  50.     np->ww_logout = time(NULL);
  51.     np->ww_online = (cptr->from != NULL) ? cptr : NULL;
  52.     np->ww_user->refcnt++;
  53.  
  54.     np2 = &was[ww_index];
  55.     if (np2->ww_user)
  56.         free_user(np2->ww_user, np2->ww_online);
  57.     /*
  58.      * New whowas handling, we keep a list of what whowas entries
  59.      * are "used" by a client, in its cptr structure.  This means
  60.      * that when we overwrite a whowas entry, we have to remove the
  61.      * relative pointer in the client. -Cabal95
  62.      */
  63.     if (np2->ww_online) {
  64.         Link    *last = NULL;
  65.  
  66.         for (lp = np2->ww_online->history; lp;
  67.              last = lp, lp = lp->next)
  68.             if (lp->value.whowas == np2)
  69.                 break;
  70.  
  71.         if (lp) {    /* Sanity check, never trust anything */
  72.             if (last)
  73.                 last->next = lp->next;
  74.             else
  75.                 np2->ww_online->history = lp->next;
  76.  
  77.             free_link(lp);
  78.         }
  79.     }
  80.  
  81.     bcopy((char *)&ntmp, (char *)np2, sizeof(aName));
  82.  
  83.     /*
  84.      * Add this whowas entry into the clients history list
  85.      */
  86.     lp = make_link();
  87.     lp->value.whowas = np2;
  88.     lp->next = cptr->history;
  89.     cptr->history = lp;
  90.  
  91.     ww_index++;
  92.     if (ww_index >= NICKNAMEHISTORYLENGTH)
  93.         ww_index = 0;
  94.     return;
  95. }
  96.  
  97. /*
  98. ** get_history
  99. **      Return the current client that was using the given
  100. **      nickname within the timelimit. Returns NULL, if no
  101. **      one found...
  102. */
  103. aClient *get_history(nick, timelimit)
  104. char    *nick;
  105. time_t  timelimit;
  106. {
  107.         Reg1    aName   *wp, *wp2;
  108.         Reg2    int     i = 0;
  109.  
  110.     if (ww_index == 0)
  111.       wp = wp2 = &was[NICKNAMEHISTORYLENGTH - 1];
  112.       else
  113.       wp = wp2 = &was[ww_index - 1];
  114.         timelimit = time(NULL)-timelimit;
  115.  
  116.     do {
  117.         if (!mycmp(nick, wp->ww_nick) && wp->ww_logout >= timelimit)
  118.             break;
  119.         if (wp == was)
  120.         {
  121.           i = 1;
  122.           wp = &was[NICKNAMEHISTORYLENGTH - 1];
  123.         }
  124.         else
  125.           wp--;
  126.     } while (wp != wp2);
  127.  
  128.     if (wp != wp2 || !i)
  129.         return (wp->ww_online);
  130.     return (NULL);
  131. }
  132.  
  133. void    off_history(cptr)
  134. Reg3    aClient    *cptr;
  135. {
  136.     Reg1    Link    *lp;
  137.     Reg2    Link    *next;
  138.  
  139.  
  140.     for (lp = cptr->history; lp; lp = next) {
  141.         next = lp->next;
  142.         lp->value.whowas->ww_online = NULL;
  143.         free_link(lp);
  144.     }
  145.  
  146.     cptr->history = NULL;
  147.  
  148.     return;
  149. }
  150.  
  151. void    initwhowas()
  152. {
  153.     Reg1    int    i;
  154.  
  155.     for (i = 0; i < NICKNAMEHISTORYLENGTH; i++)
  156.         bzero((char *)&was[i], sizeof(aName));
  157.     return;
  158. }
  159.  
  160.  
  161. /*
  162. ** m_whowas
  163. **    parv[0] = sender prefix
  164. **    parv[1] = nickname queried
  165. */
  166. int    m_whowas(cptr, sptr, parc, parv)
  167. aClient    *cptr, *sptr;
  168. int    parc;
  169. char    *parv[];
  170. {
  171.     Reg1    aName    *wp, *wp2 = NULL;
  172.     Reg2    int    j = 0;
  173.     Reg3    anUser    *up = NULL;
  174.     int    max = -1;
  175.     char    *p, *nick, *s;
  176.  
  177.      if (parc < 2)
  178.         {
  179.         sendto_one(sptr, err_str(ERR_NONICKNAMEGIVEN),
  180.                me.name, parv[0]);
  181.         return 0;
  182.         }
  183.     if (parc > 2)
  184.         max = atoi(parv[2]);
  185.     if (parc > 3)
  186.         if (hunt_server(cptr,sptr,":%s WHOWAS %s %s :%s", 3,parc,parv))
  187.             return 0;
  188.  
  189.     for (s = parv[1]; (nick = strtoken(&p, s, ",")); s = NULL)
  190.         {
  191.         wp = wp2 = &was[ww_index - 1];
  192.  
  193.         do {
  194.             if (wp < was)
  195.                 wp = &was[NICKNAMEHISTORYLENGTH - 1];
  196.             if (mycmp(nick, wp->ww_nick) == 0)
  197.                 {
  198.                 up = wp->ww_user;
  199.                 sendto_one(sptr, rpl_str(RPL_WHOWASUSER),
  200.                        me.name, parv[0], wp->ww_nick,
  201.                        up->username,
  202.                        up->host, wp->ww_info);
  203.                 sendto_one(sptr, rpl_str(RPL_WHOISSERVER),
  204.                        me.name, parv[0], wp->ww_nick,
  205.                        up->server, myctime(wp->ww_logout));
  206.                 if (up->away)
  207.                     sendto_one(sptr, rpl_str(RPL_AWAY),
  208.                            me.name, parv[0],
  209.                            wp->ww_nick, up->away);
  210.                 j++;
  211.                 }
  212.             if (max > 0 && j >= max)
  213.                 break;
  214.             wp--;
  215.         } while (wp != wp2);
  216.  
  217.         if (up == NULL)
  218.             sendto_one(sptr, err_str(ERR_WASNOSUCHNICK),
  219.                    me.name, parv[0], nick);
  220.         up=NULL;
  221.  
  222.         if (p)
  223.             p[-1] = ',';
  224.         }
  225.     sendto_one(sptr, rpl_str(RPL_ENDOFWHOWAS), me.name, parv[0], parv[1]);
  226.     return 0;
  227.     }
  228.  
  229.  
  230. void    count_whowas_memory(wwu, wwa, wwam)
  231. int    *wwu, *wwa;
  232. u_long    *wwam;
  233. {
  234.     Reg1    anUser    *tmp;
  235.     Reg2    int    i, j;
  236.     int    u = 0, a = 0;
  237.     u_long    am = 0;
  238.  
  239.     for (i = 0; i < NICKNAMEHISTORYLENGTH; i++)
  240.         if ((tmp = was[i].ww_user))
  241.             if (!was[i].ww_online)
  242.                 {
  243.                 for (j = 0; j < i; j++)
  244.                     if (was[j].ww_user == tmp)
  245.                         break;
  246.                 if (j < i)
  247.                     continue;
  248.                 u++;
  249.                 if (tmp->away)
  250.                     {
  251.                     a++;
  252.                     am += (strlen(tmp->away)+1);
  253.                     }
  254.                 }
  255.     *wwu = u;
  256.     *wwa = a;
  257.     *wwam = am;
  258.  
  259.     return;
  260. }
  261.