Logo Search packages:      
Sourcecode: rageircd version File versions  Download package

m_list.c

/*
 * RageIRCd: an advanced Internet Relay Chat daemon (ircd).
 * (C) 2000-2005 the RageIRCd Development Team, all rights reserved.
 *
 * This software is free, licensed under the General Public License.
 * Please refer to doc/LICENSE and doc/README for further details.
 *
 * $Id: m_list.c,v 1.31.2.2 2005/01/15 23:53:32 amcwilliam Exp $
 */

#include "config.h"
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "numeric.h"
#include "msg.h"
#include "channel.h"
#include "h.h"
#include "memory.h"
#include "modules.h"
#include "xmode.h"
#include <time.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>

Module MOD_HEADER(m_list) = {
      "m_list",
      "/LIST command",
      6, "$Revision: 1.31.2.2 $"
};

int MOD_LOAD(m_list)()
{
      if (register_command(&MOD_HEADER(m_list), &CMD_LIST, m_list) == NULL) {
            return MOD_FAILURE;
      }
      return MOD_SUCCESS;
}

int MOD_UNLOAD(m_list)()
{
      return MOD_SUCCESS;
}

static char *usage[] = {
      "   Usage: /RAW LIST <options> (on mIRC) or /QUOTE LIST <options> (on ircII)",
      " ",
      "If you don't include any options, the default is to send you the",
      "entire unfiltered list of channels. Below are the options you can",
      " use, and what channel LIST will return when you use them.",
      " ",
      ">number  - List channels with more than <number> people.",
      "<number  - List channels with less than <number> people.",
      "C>number - List channels created between now and <number> minutes ago.",
      "C<number - List channels created earlier than <number> minutes ago.",
      "T>number - List channels whos topics are older than <number> minutes.",
      "T<number - List channels whos topics are not older than <number> minutes.",
      "*mask*   - List channels that match *mask*.",
      "!*mask*  - List channels that do not match *mask*.",
      NULL
};

/*
 * m_list
 *    parv[0] = sender prefix
 *    parv[1] = channel
 */
int m_list(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
      char mode_buf[REALMODEBUFLEN], para_buf[REALMODEBUFLEN];
      aChannel *chptr;
      time_t currenttime = timeofday, chantimemin, chantimemax;
      time_t topictimemin, topictimemax;
      char *name, *p = NULL;
      char modestuff[TOPICLEN + 3 + KEYLEN + 8 + 3 + 1], tmpbuf[3 + KEYLEN + 8 + 3 + 1];
      LOpts *lopt = NULL;
      SLink *lp, *yeslist = NULL, *nolist = NULL;
      int usermax, usermin, error = 0, doall = 0;

      if (cptr != sptr || sptr->localUser == NULL) {
            return 0;
      }

      if ((lopt = sptr->localUser->lopt) != NULL) {
            SLink *next;

            send_me_numericNA(sptr, RPL_LISTEND);
            for (lp = lopt->yeslist; lp != NULL; lp = next) {
                  next = lp->next;
                  MyFree(lp->value.cp);
                  free_slink(lp);
            }
            for (lp = lopt->nolist; lp != NULL; lp = next) {
                  next = lp->next;
                  MyFree(lp->value.cp);
                  free_slink(lp);
            }

            MyFree(sptr->localUser->lopt);
            sptr->localUser->lopt = NULL;

            dlink_del(&listingcli_list, sptr, NULL);
            return 0;
      }
      if (parc < 2 || *parv[1] == '\0') {
            send_me_numericNA(sptr, RPL_LISTSTART);
            lopt = sptr->localUser->lopt = (LOpts *)MyMalloc(sizeof(LOpts));
            lopt->showall = 1;

            dlink_add(&listingcli_list, sptr);

            if (SBufLength(&cptr->localClient->sendQ) < 2048) {
                  send_list(cptr, 64);
            }

            return 0;
      }
      if (parc == 2 && parv[1][0] == '?' && parv[1][1] == '\0') {
            char **ptr = usage;
            for (; *ptr; ptr++) {
                  send_me_numeric(sptr, RPL_COMMANDSYNTAX, *ptr);
            }
            return 0;
      }

      send_me_numericNA(sptr, RPL_LISTSTART);

      chantimemax = topictimemax = currenttime + 86400;
      chantimemin = topictimemin = 0;
      usermin = 1;
      usermax = -1;

      for (name = strtoken(&p, parv[1], ","); name != NULL && !error; name = strtoken(&p, NULL, ",")) {
            switch (*name) {
                  case '<':
                        usermax = atoi(name + 1) - 1;
                        doall = 1;
                        break;
                  case '>':
                        usermin = atoi(name + 1) + 1;
                        doall = 1;
                        break;
                  case 'C':
                  case 'c':
                        name++;
                        switch (*name++) {
                              case '<':
                                    chantimemax = currenttime - 60 * atoi(name);
                                    doall = 1;
                                    break;
                              case '>':
                                    chantimemin = currenttime - 60 * atoi(name);
                                    doall = 1;
                                    break;
                              default:
                                    send_me_numericNA(sptr, ERR_LISTSYNTAX);
                                    error = 1;
                        }
                        break;
                  case 'T':
                  case 't':
                        name++;
                        switch (*name++) {
                              case '<':
                                    topictimemax = currenttime - 60 * atoi(name);
                                    doall = 1;
                                    break;
                              case '>':
                                    topictimemin = currenttime - 60 * atoi(name);
                                    doall = 1;
                                    break;
                              default:
                                    send_me_numericNA(sptr, ERR_LISTSYNTAX);
                                    error = 1;
                        }
                        break;
                  default:
                        if (*name == '!') {
                              doall = 1;
                              lp = make_slink();
                              lp->next = nolist;
                              nolist = lp;
                              DupString(lp->value.cp, name + 1);
                        }
                        else if (strchr(name, '*') != NULL || strchr(name, '*') != NULL) {
                              doall = 1;
                              lp = make_slink();
                              lp->next = yeslist;
                              nolist = lp;
                              DupString(lp->value.cp, name);
                        }
                        else {
                              if ((chptr = find_channel(name, NULL)) != NULL) {
                                    if (HasMode(sptr, UMODE_SADMIN)) {
                                          get_chan_modes(sptr, chptr, mode_buf, para_buf);

                                          ircsprintf(tmpbuf, " [%s%s%s]", mode_buf,
                                                *para_buf ? " " : "",
                                                *para_buf ? para_buf : "");
                                          ircsprintf(modestuff, "%-2s %s", tmpbuf, chptr->topic);

                                          send_me_numeric(sptr, RPL_LIST, name, chptr->users,
                                                modestuff);
                                    }
                                    else if (ShowChannel(sptr, chptr)) {
                                          send_me_numeric(sptr, RPL_LIST, name, chptr->users,
                                                chptr->topic);
                                    }
                              }
                        }
            }
      }

      if (doall) {
            lopt = sptr->localUser->lopt = (LOpts *)MyMalloc(sizeof(LOpts));
            lopt->usermax = usermax;
            lopt->usermin = usermin;
            lopt->chantimemax = chantimemax;
            lopt->chantimemin = chantimemin;
            lopt->topictimemax = topictimemax;
            lopt->topictimemin = topictimemin;
            lopt->yeslist = yeslist;
            lopt->nolist = nolist;

            dlink_add(&listingcli_list, sptr);

            if (SBufLength(&cptr->localClient->sendQ) < 2048) {
                  send_list(cptr, 64);
            }
      }
      else {
            send_me_numericNA(sptr, RPL_LISTEND);
      }
      return 0;
}

Generated by  Doxygen 1.6.0   Back to index