home *** CD-ROM | disk | FTP | other *** search
/ The Net: Ultimate Internet Guide / WWLCD1.ISO / pc / java / in4wjcxu / other / irc / ircd / list.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-14  |  9.4 KB  |  448 lines

  1. /************************************************************************
  2.  *   IRC - Internet Relay Chat, ircd/list.c
  3.  *   Copyright (C) 1990 Jarkko Oikarinen and
  4.  *                      University of Oulu, Finland
  5.  *
  6.  *   This program is free software; you can redistribute it and/or modify
  7.  *   it under the terms of the GNU General Public License as published by
  8.  *   the Free Software Foundation; either version 1, or (at your option)
  9.  *   any later version.
  10.  *
  11.  *   This program is distributed in the hope that it will be useful,
  12.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *   GNU General Public License for more details.
  15.  *
  16.  *   You should have received a copy of the GNU General Public License
  17.  *   along with this program; if not, write to the Free Software
  18.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. /* -- Jto -- 20 Jun 1990
  22.  * extern void free() fixed as suggested by
  23.  * gruner@informatik.tu-muenchen.de
  24.  */
  25.  
  26. /* -- Jto -- 03 Jun 1990
  27.  * Added chname initialization...
  28.  */
  29.  
  30. /* -- Jto -- 24 May 1990
  31.  * Moved is_full() to channel.c
  32.  */
  33.  
  34. /* -- Jto -- 10 May 1990
  35.  * Added #include <sys.h>
  36.  * Changed memset(xx,0,yy) into bzero(xx,yy)
  37.  */
  38.  
  39. #ifndef lint
  40. static  char sccsid[] = "@(#)list.c    2.24 4/20/94 (C) 1988 University of Oulu, \
  41. Computing Center and Jarkko Oikarinen";
  42. #endif
  43.  
  44. #include "struct.h"
  45. #include "common.h"
  46. #include "sys.h"
  47. #include "h.h"
  48. #include "numeric.h"
  49. #ifdef    DBMALLOC
  50. #include "malloc.h"
  51. #endif
  52. void    free_link PROTO((Link *));
  53. Link    *make_link PROTO(());
  54.  
  55. #ifdef    DEBUGMODE
  56. static    struct    liststats {
  57.     int    inuse;
  58. } cloc, crem, users, servs, links, classs, aconfs;
  59.  
  60. #endif
  61.  
  62. void    outofmemory();
  63.  
  64. int    numclients = 0;
  65.  
  66. void    initlists()
  67. {
  68. #ifdef    DEBUGMODE
  69.     bzero((char *)&cloc, sizeof(cloc));
  70.     bzero((char *)&crem, sizeof(crem));
  71.     bzero((char *)&users, sizeof(users));
  72.     bzero((char *)&servs, sizeof(servs));
  73.     bzero((char *)&links, sizeof(links));
  74.     bzero((char *)&classs, sizeof(classs));
  75.     bzero((char *)&aconfs, sizeof(aconfs));
  76. #endif
  77. }
  78.  
  79. void    outofmemory()
  80. {
  81.     Debug((DEBUG_FATAL, "Out of memory: restarting server..."));
  82.     restart("Out of Memory");
  83. }
  84.  
  85.     
  86. /*
  87. ** Create a new aClient structure and set it to initial state.
  88. **
  89. **    from == NULL,    create local client (a client connected
  90. **            to a socket).
  91. **
  92. **    from,    create remote client (behind a socket
  93. **            associated with the client defined by
  94. **            'from'). ('from' is a local client!!).
  95. */
  96. aClient    *make_client(from)
  97. aClient    *from;
  98. {
  99.     Reg1    aClient *cptr = NULL;
  100.     Reg2    unsigned size = CLIENT_REMOTE_SIZE;
  101.  
  102.     /*
  103.      * Check freelists first to see if we can grab a client without
  104.      * having to call malloc.
  105.      */
  106.     if (!from)
  107.         size = CLIENT_LOCAL_SIZE;
  108.  
  109.     if (!(cptr = (aClient *)MyMalloc(size)))
  110.         outofmemory();
  111.     bzero((char *)cptr, (int)size);
  112.  
  113. #ifdef    DEBUGMODE
  114.     if (size == CLIENT_LOCAL_SIZE)
  115.         cloc.inuse++;
  116.     else
  117.         crem.inuse++;
  118. #endif
  119.  
  120.     /* Note:  structure is zero (calloc) */
  121.     cptr->from = from ? from : cptr; /* 'from' of local client is self! */
  122.     cptr->next = NULL; /* For machines with NON-ZERO NULL pointers >;) */
  123.     cptr->prev = NULL;
  124.     cptr->hnext = NULL;
  125.     cptr->user = NULL;
  126.     cptr->serv = NULL;
  127.     cptr->status = STAT_UNKNOWN;
  128.     cptr->fd = -1;
  129.     (void)strcpy(cptr->username, "unknown");
  130.     if (size == CLIENT_LOCAL_SIZE)
  131.         {
  132.         cptr->since = cptr->lasttime = cptr->firsttime = time(NULL);
  133.         cptr->confs = NULL;
  134.         cptr->sockhost[0] = '\0';
  135.         cptr->buffer[0] = '\0';
  136.         cptr->authfd = -1;
  137.         }
  138.     return (cptr);
  139. }
  140.  
  141. void    free_client(cptr)
  142. aClient    *cptr;
  143. {
  144.     MyFree((char *)cptr);
  145. }
  146.  
  147. /*
  148. ** 'make_user' add's an User information block to a client
  149. ** if it was not previously allocated.
  150. */
  151. anUser    *make_user(cptr)
  152. aClient *cptr;
  153. {
  154.     Reg1    anUser    *user;
  155.  
  156.     user = cptr->user;
  157.     if (!user)
  158.         {
  159.         user = (anUser *)MyMalloc(sizeof(anUser));
  160. #ifdef    DEBUGMODE
  161.         users.inuse++;
  162. #endif
  163.         user->away = NULL;
  164.         user->refcnt = 1;
  165.         user->joined = 0;
  166.         user->channel = NULL;
  167.         user->invited = NULL;
  168.         cptr->user = user;
  169.         }
  170.     return user;
  171. }
  172.  
  173. aServer    *make_server(cptr)
  174. aClient    *cptr;
  175. {
  176.     Reg1    aServer    *serv = cptr->serv;
  177.  
  178.     if (!serv)
  179.         {
  180.         serv = (aServer *)MyMalloc(sizeof(aServer));
  181. #ifdef    DEBUGMODE
  182.         servs.inuse++;
  183. #endif
  184.         serv->user = NULL;
  185.         serv->nexts = NULL;
  186.         *serv->by = '\0';
  187.         *serv->up = '\0';
  188.         cptr->serv = serv;
  189.         }
  190.     return cptr->serv;
  191. }
  192.  
  193. /*
  194. ** free_user
  195. **    Decrease user reference count by one and realease block,
  196. **    if count reaches 0
  197. */
  198. void    free_user(user, cptr)
  199. Reg1    anUser    *user;
  200. aClient    *cptr;
  201. {
  202.     if (--user->refcnt <= 0)
  203.         {
  204.         if (user->away)
  205.             MyFree((char *)user->away);
  206.         /*
  207.          * sanity check
  208.          */
  209.         if (user->joined || user->refcnt < 0 ||
  210.             user->invited || user->channel)
  211. #ifdef DEBUGMODE
  212.             dumpcore("%#x user (%s!%s@%s) %#x %#x %#x %d %d",
  213.                 cptr, cptr ? cptr->name : "<noname>",
  214.                 user->username, user->host, user,
  215.                 user->invited, user->channel, user->joined,
  216.                 user->refcnt);
  217. #else
  218.             sendto_ops("* %#x user (%s!%s@%s) %#x %#x %#x %d %d *",
  219.                 cptr, cptr ? cptr->name : "<noname>",
  220.                 user->username, user->host, user,
  221.                 user->invited, user->channel, user->joined,
  222.                 user->refcnt);
  223. #endif
  224.         MyFree((char *)user);
  225. #ifdef    DEBUGMODE
  226.         users.inuse--;
  227. #endif
  228.         }
  229. }
  230.  
  231. /*
  232.  * taken the code from ExitOneClient() for this and placed it here.
  233.  * - avalon
  234.  */
  235. void    remove_client_from_list(cptr)
  236. Reg1    aClient    *cptr;
  237. {
  238.     checklist();
  239.     if (cptr->prev)
  240.         cptr->prev->next = cptr->next;
  241.     else
  242.         {
  243.         client = cptr->next;
  244.         client->prev = NULL;
  245.         }
  246.     if (cptr->next)
  247.         cptr->next->prev = cptr->prev;
  248.     if (IsPerson(cptr) && cptr->user)
  249.         {
  250.         add_history(cptr);
  251.         off_history(cptr);
  252.         }
  253.     if (cptr->user)
  254.         (void)free_user(cptr->user, cptr);
  255.     if (cptr->serv)
  256.         {
  257.         if (cptr->serv->user)
  258.             free_user(cptr->serv->user, cptr);
  259.         MyFree((char *)cptr->serv);
  260. #ifdef    DEBUGMODE
  261.         servs.inuse--;
  262. #endif
  263.         }
  264. #ifdef    DEBUGMODE
  265.     if (cptr->fd == -2)
  266.         cloc.inuse--;
  267.     else
  268.         crem.inuse--;
  269. #endif
  270.     (void)free_client(cptr);
  271.     numclients--;
  272.     return;
  273. }
  274.  
  275. /*
  276.  * although only a small routine, it appears in a number of places
  277.  * as a collection of a few lines...functions like this *should* be
  278.  * in this file, shouldnt they ?  after all, this is list.c, isnt it ?
  279.  * -avalon
  280.  */
  281. void    add_client_to_list(cptr)
  282. aClient    *cptr;
  283. {
  284.     /*
  285.      * since we always insert new clients to the top of the list,
  286.      * this should mean the "me" is the bottom most item in the list.
  287.      */
  288.     cptr->next = client;
  289.     client = cptr;
  290.     if (cptr->next)
  291.         cptr->next->prev = cptr;
  292.     return;
  293. }
  294.  
  295. /*
  296.  * Look for ptr in the linked listed pointed to by link.
  297.  */
  298. Link    *find_user_link(lp, ptr)
  299. Reg1    Link    *lp;
  300. Reg2    aClient *ptr;
  301. {
  302.     while (lp && ptr)
  303.        {
  304.         if (lp->value.cptr == ptr)
  305.             return (lp);
  306.         lp = lp->next;
  307.         }
  308.     return NULL;
  309. }
  310.  
  311. Link    *make_link()
  312. {
  313.     Reg1    Link    *lp;
  314.  
  315.     lp = (Link *)MyMalloc(sizeof(Link));
  316. #ifdef    DEBUGMODE
  317.     links.inuse++;
  318. #endif
  319.     return lp;
  320. }
  321.  
  322. void    free_link(lp)
  323. Reg1    Link    *lp;
  324. {
  325.     MyFree((char *)lp);
  326. #ifdef    DEBUGMODE
  327.     links.inuse--;
  328. #endif
  329. }
  330.  
  331.  
  332. aClass    *make_class()
  333. {
  334.     Reg1    aClass    *tmp;
  335.  
  336.     tmp = (aClass *)MyMalloc(sizeof(aClass));
  337. #ifdef    DEBUGMODE
  338.     classs.inuse++;
  339. #endif
  340.     return tmp;
  341. }
  342.  
  343. void    free_class(tmp)
  344. Reg1    aClass    *tmp;
  345. {
  346.     MyFree((char *)tmp);
  347. #ifdef    DEBUGMODE
  348.     classs.inuse--;
  349. #endif
  350. }
  351.  
  352. aConfItem    *make_conf()
  353. {
  354.     Reg1    aConfItem *aconf;
  355.  
  356.     aconf = (struct ConfItem *)MyMalloc(sizeof(aConfItem));
  357. #ifdef    DEBUGMODE
  358.     aconfs.inuse++;
  359. #endif
  360.     bzero((char *)&aconf->ipnum, sizeof(struct in_addr));
  361.     aconf->next = NULL;
  362.     aconf->host = aconf->passwd = aconf->name = NULL;
  363.     aconf->status = CONF_ILLEGAL;
  364.     aconf->clients = 0;
  365.     aconf->port = 0;
  366.     aconf->hold = 0;
  367.     Class(aconf) = 0;
  368.     return (aconf);
  369. }
  370.  
  371. void    delist_conf(aconf)
  372. aConfItem    *aconf;
  373. {
  374.     if (aconf == conf)
  375.         conf = conf->next;
  376.     else
  377.         {
  378.         aConfItem    *bconf;
  379.  
  380.         for (bconf = conf; aconf != bconf->next; bconf = bconf->next)
  381.             ;
  382.         bconf->next = aconf->next;
  383.         }
  384.     aconf->next = NULL;
  385. }
  386.  
  387. void    free_conf(aconf)
  388. aConfItem *aconf;
  389. {
  390.     del_queries((char *)aconf);
  391.     MyFree(aconf->host);
  392.     if (aconf->passwd)
  393.         bzero(aconf->passwd, strlen(aconf->passwd));
  394.     MyFree(aconf->passwd);
  395.     MyFree(aconf->name);
  396.     MyFree((char *)aconf);
  397. #ifdef    DEBUGMODE
  398.     aconfs.inuse--;
  399. #endif
  400.     return;
  401. }
  402.  
  403. #ifdef    DEBUGMODE
  404. void    send_listinfo(cptr, name)
  405. aClient    *cptr;
  406. char    *name;
  407. {
  408.     int    inuse = 0, mem = 0, tmp = 0;
  409.  
  410.     sendto_one(cptr, ":%s %d %s :Local: inuse: %d(%d)",
  411.            me.name, RPL_STATSDEBUG, name, inuse += cloc.inuse,
  412.            tmp = cloc.inuse * CLIENT_LOCAL_SIZE);
  413.     mem += tmp;
  414.     sendto_one(cptr, ":%s %d %s :Remote: inuse: %d(%d)",
  415.            me.name, RPL_STATSDEBUG, name,
  416.            crem.inuse, tmp = crem.inuse * CLIENT_REMOTE_SIZE);
  417.     mem += tmp;
  418.     inuse += crem.inuse;
  419.     sendto_one(cptr, ":%s %d %s :Users: inuse: %d(%d)",
  420.            me.name, RPL_STATSDEBUG, name, users.inuse,
  421.            tmp = users.inuse * sizeof(anUser));
  422.     mem += tmp;
  423.     inuse += users.inuse,
  424.     sendto_one(cptr, ":%s %d %s :Servs: inuse: %d(%d)",
  425.            me.name, RPL_STATSDEBUG, name, servs.inuse,
  426.            tmp = servs.inuse * sizeof(aServer));
  427.     mem += tmp;
  428.     inuse += servs.inuse,
  429.     sendto_one(cptr, ":%s %d %s :Links: inuse: %d(%d)",
  430.            me.name, RPL_STATSDEBUG, name, links.inuse,
  431.            tmp = links.inuse * sizeof(Link));
  432.     mem += tmp;
  433.     inuse += links.inuse,
  434.     sendto_one(cptr, ":%s %d %s :Classes: inuse: %d(%d)",
  435.            me.name, RPL_STATSDEBUG, name, classs.inuse,
  436.            tmp = classs.inuse * sizeof(aClass));
  437.     mem += tmp;
  438.     inuse += classs.inuse,
  439.     sendto_one(cptr, ":%s %d %s :Confs: inuse: %d(%d)",
  440.            me.name, RPL_STATSDEBUG, name, aconfs.inuse,
  441.            tmp = aconfs.inuse * sizeof(aConfItem));
  442.     mem += tmp;
  443.     inuse += aconfs.inuse,
  444.     sendto_one(cptr, ":%s %d %s :Totals: inuse %d %d",
  445.            me.name, RPL_STATSDEBUG, name, inuse, mem);
  446. }
  447. #endif
  448.