/* * IRC - Internet Relay Chat, ircd/m_watch.c * Copyright (C) 1990 Jarkko Oikarinen and * University of Oulu, Computing Center * Copyright (C) 2002-2007 IRC-Dev Development Team * Copyright (C) 2002 Toni Garcia (zoltan) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id$ */ #include "config.h" #include "client.h" #include "hash.h" #include "ircd.h" #include "ircd_features.h" #include "ircd_log.h" #include "ircd_reply.h" #include "ircd_string.h" #include "list.h" #include "numeric.h" #include "s_user.h" #include "send.h" #include "watch.h" /* #include -- Now using assert in ircd_log.h */ #include #include /* * m_watch - generic message handler * * parv[0] = sender prefix * parv[1] = parametres * * The parv[1] can be separated parameters with "," or " " or both. * If a parameter begins by '+', adds a nick. * And if a parameter begins by '-' deletes a nick. * If to a 'C' or 'c' is sent, deletes all the watch list. * A 'S' or 's' gives the notify status. * The parameter 'l' list nicks on-line and 'L' list nicks on-line and off-line. * * By default, the parameter is a 'l'. * * 2002/05/20 zoltan */ int m_watch(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) { char *s, *p = 0; int i = 0; if (parc < 2) { /* Default parameter 'l' */ parc = 2; parv[1] = "l"; } /* * The parameters can be separated for " " or "," or both. */ for (i = 0; i < parc; i++) { for (s = ircd_strtok(&p, parv[i], ", "); s; s = ircd_strtok(&p, NULL, ", ")) { /* * Prefix: "+" (add) "-" (delete) */ if (*s == '+' || *s == '-') { char *nick, *p2; char c = *s; *s++ = '\0'; /* If nick!user@host is received we truncated it */ if (!(nick = ircd_strtok(&p2, s, "!"))) nick = s; /* Do not admit servers, neither @, nor jockers */ if (strchr(nick, '*') || strchr(nick, '.') || strchr(nick, '@')) continue; if (strlen(nick) > NICKLEN) nick[NICKLEN] = '\0'; if (!*nick) continue; if (c == '+') /* Add nick */ { if (cli_user(sptr)->watches >= feature_int(FEAT_MAXWATCHS)) { send_reply(sptr, ERR_TOOMANYWATCH, nick, feature_int(FEAT_MAXWATCHS)); continue; } add_nick_watch(sptr, nick); show_status_watch(sptr, nick, RPL_NOWON, RPL_NOWOFF); } else if (c == '-') /* Deletes nick */ { del_nick_watch(sptr, nick); show_status_watch(sptr, nick, RPL_WATCHOFF, RPL_WATCHOFF); } continue; } /* * Parameter C/c * * Deletes all the WATCH list. */ if (*s == 'C' || *s == 'c') { del_list_watch(sptr); continue; } /* * Parametr S/s * * Status the WATCH List. */ if (*s == 'S' || *s == 's') { struct Watch *wptr; struct SLink *lp; char line[BUFSIZE * 2]; int count = 0; wptr = FindWatch(cli_name(sptr)); if (wptr) for (lp = wt_watch(wptr), count = 1; (lp = lp->next); count++); send_reply(sptr, RPL_WATCHSTAT, cli_user(sptr)->watches, count); lp = cli_user(sptr)->watch; if (lp) { *line = '\0'; strcpy(line, lp->value.wptr->wt_nick); count = strlen(parv[0]) + strlen(cli_name(&me)) + 10 + strlen(line); while ((lp = lp->next)) { if ((count + strlen(lp->value.wptr->wt_nick) + 1) > 512) { send_reply(sptr, RPL_WATCHLIST, line); *line = '\0'; count = strlen(cli_name(sptr)) + strlen(cli_name(&me)) + 10; } strcat(line, " "); strcat(line, lp->value.wptr->wt_nick); count += (strlen(lp->value.wptr->wt_nick) + 1); } send_reply(sptr, RPL_WATCHLIST, line); } send_reply(sptr, RPL_ENDOFWATCHLIST, *s); continue; } /* * Parameter L/l * * List users online and if we also especified "L" offline. */ if (*s == 'L' || *s == 'l') { struct Client *acptr; struct SLink *lp = cli_user(sptr)->watch; while (lp) { if ((acptr = FindUser(lp->value.wptr->wt_nick))) { send_reply(sptr, RPL_NOWON, cli_name(acptr), cli_user(acptr)->username, !IsAnOper(sptr) ? cli_user(acptr)->host : cli_user(acptr)->realhost, cli_lastnick(acptr)); } /* * If it specifies "L" to also send off-line. */ else if (*s == 'L') { send_reply(sptr, RPL_NOWOFF, lp->value.wptr->wt_nick, "*", "*", lp->value.wptr->wt_lasttime); } lp = lp->next; } send_reply(sptr, RPL_ENDOFWATCHLIST, *s); continue; } /* Unknown or not supported parameter. * Ignored it :) */ } } return 0; }