Esempio n. 1
0
/*
 * mo_rehash - oper message handler
 * 
 * parv[1] = 'm' flushes the MOTD cache and returns
 * parv[1] = 'l' reopens the log files and returns
 * parv[1] = 'q' to not rehash the resolver (optional)
 * parv[1] = 's' to reload SSL certificates
 * parv[1] = 'a' to restart the IAuth program
 */
int mo_rehash(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  int flag = 0;

  if (!HasPriv(sptr, PRIV_REHASH) || ((parc == 3) && !HasPriv(sptr, PRIV_REMOTEREHASH)))
    return send_reply(sptr, ERR_NOPRIVILEGES);

  if ((parc == 3) && (hunt_server_cmd(sptr, CMD_REHASH, cptr, 1, "%s %C", 2, parc, parv) != HUNTED_ISME))
    return 0;

  if (parc == 2) { /* special processing */
    if (parv[1][1] == '\0') { /* one character server name */
      if (*parv[1] == 'm') {
        send_reply(sptr, SND_EXPLICIT | RPL_REHASHING, ":Flushing MOTD cache");
        motd_recache(); /* flush MOTD cache */
        return 0;
      } else if (*parv[1] == 'l') {
        send_reply(sptr, SND_EXPLICIT | RPL_REHASHING, ":Reopening log files");
        log_reopen(); /* reopen log files */
        return 0;
      } else if (*parv[1] == 'a') {
        send_reply(sptr, SND_EXPLICIT | RPL_REHASHING, ":Restarting IAuth");
        auth_restart(); /* Restart IAuth program */
        return 0;
#ifdef USE_SSL
      } else if (*parv[1] == 's') {
        send_reply(sptr, SND_EXPLICIT | RPL_REHASHING, ":Reloading SSL certificates");
        ssl_reinit();
        return 0;
#endif
      } else if (*parv[1] == 'q')
        flag = 2;
    }
    /*
     * Maybe the user wants to rehash another server with no parameters.
     * NOTE: Here we assume that there are no servers named
     * 'm', 'l', 's', or 'q'.
     */
    else
      if (HasPriv(sptr, PRIV_REMOTEREHASH)) {
        if (hunt_server_cmd(sptr, CMD_REHASH, cptr, 1, "%C", 1, parc, parv) != HUNTED_ISME)
          return 0;
      } else
        return send_reply(sptr, ERR_NOPRIVILEGES);
  }

  send_reply(sptr, RPL_REHASHING, configfile);
  sendto_opmask_butone(0, SNO_OLDSNO, "%C is rehashing Server config file",
		       sptr);

  log_write(LS_SYSTEM, L_INFO, 0, "REHASH From %#C", sptr);

  return rehash(cptr, flag);
}
Esempio n. 2
0
int ms_rehash(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  int flag = 0;

  if ((parc > 2) && (hunt_server_cmd(sptr, CMD_REHASH, cptr, 1, "%s %C", 2, parc, parv) != HUNTED_ISME))
    return 0;

  /* OK, the message has been forwarded, but before we can act... */
  if (!feature_bool(FEAT_NETWORK_REHASH))
    return 0;

  if (parc > 1) { /* special processing */
    if (parv[1][1] == '\0') { /* one character server name */
      if (*parv[1] == 'm') {
        send_reply(sptr, SND_EXPLICIT | RPL_REHASHING, ":Flushing MOTD cache");
        motd_recache(); /* flush MOTD cache */
        return 0;
      } else if (*parv[1] == 'l') {
        send_reply(sptr, SND_EXPLICIT | RPL_REHASHING, ":Reopening log files");
        log_reopen(); /* reopen log files */
        return 0;
      } else if (*parv[1] == 'a') {
        send_reply(sptr, SND_EXPLICIT | RPL_REHASHING, ":Restarting IAuth");
        auth_restart(); /* Restart IAuth program */
        return 0;
#ifdef USE_SSL
      } else if (*parv[1] == 's') {
        send_reply(sptr, SND_EXPLICIT | RPL_REHASHING, ":Reloading SSL certificates");
        ssl_reinit();
        return 0;
#endif
      } else if (*parv[1] == 'q')
        flag = 2;
    }
    /*
     * Maybe the user wants to rehash another server with no parameters.
     * NOTE: Here we assume that there are no servers named
     * 'm', 'l', 's', or 'q'.
     */
    else if ((parc == 2) && (hunt_server_cmd(sptr, CMD_REHASH, cptr, 1, "%C", 1, parc, parv) != HUNTED_ISME))
      return 0;
  }

  send_reply(sptr, RPL_REHASHING, configfile);
  sendto_opmask_butone(0, SNO_OLDSNO, "%C [%s] is remotely rehashing Server config file",
                       sptr, cli_name(cli_user(sptr)->server));

  log_write(LS_SYSTEM, L_INFO, 0, "Remote REHASH From %#C [%s]", sptr, cli_name(cli_user(sptr)->server));

  return rehash(cptr, flag);
}
Esempio n. 3
0
/** Handle a RESTART message from a server connection.
 *
 * \a parv has the following elements:
 * \li \a parv[1] is the target server, or "*" for all.
 * \li \a parv[2] is either "cancel" or a time interval in seconds
 * \li \a parv[\a parc - 1] is the reason
 *
 * All fields must be present.  Additionally, the time interval should
 * not be 0 for messages sent to "*", as that may not function
 * reliably due to buffering in the server.
 *
 * See @ref m_functions for discussion of the arguments.
 * @param[in] cptr Client that sent us the message.
 * @param[in] sptr Original source of message.
 * @param[in] parc Number of arguments.
 * @param[in] parv Argument vector.
 */
int ms_restart(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  const char *target, *when, *reason;

  if (parc < 4)
    return need_more_params(sptr, "RESTART");

  target = parv[1];
  when = parv[2];
  reason = parv[parc - 1];

  /* is it a message we should pay attention to? */
  if (target[0] != '*' || target[1] != '\0') {
    if (hunt_server_cmd(sptr, CMD_RESTART, cptr, 0, "%C %s :%s", 1, parc, parv)
    != HUNTED_ISME)
      return 0;
  } else /* must forward the message */
    sendcmdto_serv(sptr, CMD_RESTART, cptr, "* %s :%s", when, reason);

  /* OK, the message has been forwarded, but before we can act... */
  if (!feature_bool(FEAT_NETWORK_RESTART))
    return 0;

  /* is it a cancellation? */
  if (!ircd_strcmp(when, "cancel"))
    exit_cancel(sptr); /* cancel a pending exit */
  else /* schedule an exit */
    exit_schedule(1, atoi(when), sptr, reason);

  return 0;
}
Esempio n. 4
0
/*
 * mo_info - oper message handler
 *
 * parv[0] = sender prefix
 * parv[1] = servername
 */
int mo_info(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  const char **text = infotext;

  if (hunt_server_cmd(sptr, CMD_INFO, cptr, 1, ":%C", 1, parc, parv) ==
      HUNTED_ISME)
  {
    while (text[212])
    {
      if (!IsOper(sptr))
	send_reply(sptr, RPL_INFO, *text);
      text++;
    }
    if (IsOper(sptr) && (NULL != parv[1]))
    {
      while (*text)
	send_reply(sptr, RPL_INFO, *text++);
      send_reply(sptr, RPL_INFO, "");
    }
    send_reply(sptr, SND_EXPLICIT | RPL_INFO, ":Birth Date: %s, compile # %s",
	       creation, generation);
    send_reply(sptr, SND_EXPLICIT | RPL_INFO, ":On-line since %s",
	       myctime(cli_firsttime(&me)));
    send_reply(sptr, RPL_ENDOFINFO);
  }
  return 0;
}
/*
 * mo_version - oper message handler
 *
 *   parv[0] = sender prefix
 *   parv[1] = servername
 */
int mo_version(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  struct Client *acptr;

  if (MyConnect(sptr) && parc > 1)
  {
    if (!(acptr = find_match_server(parv[1])))
    {
      send_reply(sptr, ERR_NOSUCHSERVER, parv[1]);
      return 0;
    }
    parv[1] = cli_name(acptr);
  }

  if (hunt_server_cmd(sptr, CMD_VERSION, cptr, feature_int(FEAT_HIS_REMOTE),
                                                           ":%C", 1,
                                                           parc, parv)
                      == HUNTED_ISME)
  {
    send_reply(sptr, RPL_VERSION, version, debugmode, cli_name(&me),
	       debug_serveropts());
    send_supported(sptr);
  }

  return 0;
}
Esempio n. 6
0
/*
 * ms_links - server message handler
 *
 * parv[0] = sender prefix
 * parv[1] = servername mask
 *
 * or
 *
 * parv[0] = sender prefix
 * parv[1] = server to query
 * parv[2] = servername mask
 */
int
ms_links(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
 {
   char *mask;
   struct Client *acptr;

   if (parc > 2)
   {
     if (hunt_server_cmd(sptr, CMD_LINKS, cptr, 1, "%C :%s", 1, parc, parv) !=
         HUNTED_ISME)
       return 0;
     mask = parv[2];
   }
   else
     mask = parc < 2 ? 0 : parv[1];
 
   for (acptr = GlobalClientList, collapse(mask); acptr; acptr = cli_next(acptr))
   {
     if (!IsServer(acptr) && !IsMe(acptr))
       continue;
     if (!BadPtr(mask) && match(mask, cli_name(acptr)))
       continue;
     send_reply(sptr, RPL_LINKS, cli_name(acptr), cli_name(cli_serv(acptr)->up),
                cli_hopcount(acptr), cli_serv(acptr)->prot,
                ((cli_info(acptr))[0] ? cli_info(acptr) : "(Unknown Location)"));
   }
 
   send_reply(sptr, RPL_ENDOFLINKS, BadPtr(mask) ? "*" : mask);
   return 0;
 }
/*
 * ms_motd - server message handler
 *
 * parv[0] - sender prefix
 * parv[1] - servername
 *
 * modified 30 mar 1995 by flux ([email protected])
 * T line patch - display motd based on hostmask
 * modified again 7 sep 97 by Ghostwolf with code and ideas 
 * stolen from comstud & Xorath.  All motd files are read into
 * memory in read_motd() in s_conf.c
 *
 * Now using the motd_* family of functions defined in motd.c
 */
int ms_motd(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  if (hunt_server_cmd(sptr, CMD_MOTD, cptr, 0, "%C", 1, parc, parv) !=
      HUNTED_ISME)
    return 0;

  return motd_send(sptr);
}
Esempio n. 8
0
/*
 * ms_rules - server message handler
 *
 * parv[0] - sender prefix
 * parv[1] - servername
 */
int ms_rules(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  if (hunt_server_cmd(sptr, CMD_RULES, cptr, 0, "%C", 1, parc, parv) !=
      HUNTED_ISME)
    return 0;

  return motd_send_type(sptr, MOTD_RULES);
}
/*
 * m_motd - generic message handler
 *
 * parv[0] - sender prefix
 * parv[1] - servername
 *
 * modified 30 mar 1995 by flux ([email protected])
 * T line patch - display motd based on hostmask
 * modified again 7 sep 97 by Ghostwolf with code and ideas 
 * stolen from comstud & Xorath.  All motd files are read into
 * memory in read_motd() in s_conf.c
 *
 * Now using the motd_* family of functions defined in motd.c
 */
int m_motd(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  if (hunt_server_cmd(sptr, CMD_MOTD, cptr, feature_int(FEAT_HIS_REMOTE),
		      "%C", 1, parc, parv) != HUNTED_ISME)
    return 0;

  return motd_send(sptr);
}
Esempio n. 10
0
/*
 * ms_whois - server message handler
 *
 * parv[0] = sender prefix
 * parv[1] = nickname masklist
 *
 * or
 *
 * parv[1] = target server, or a nickname representing a server to target.
 * parv[2] = nickname masklist
 */
int ms_whois(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  char*           nick;
  char*           tmp;
  char*           p = 0;
  int             found = 0;
  int		  total = 0;

  if (parc < 2)
  {
    send_reply(sptr, ERR_NONICKNAMEGIVEN);
    return 0;
  }

  if (parc > 2)
  {
    if (hunt_server_cmd(sptr, CMD_WHOIS, cptr, 0, "%C :%s", 1, parc, parv) !=
        HUNTED_ISME)
      return 0;
    parv[1] = parv[2];
  }

  total = 0;
  
  for (tmp = parv[1]; (nick = ircd_strtok(&p, tmp, ",")); tmp = 0)
  {
    struct Client *acptr = 0;

    found = 0;
    
    collapse(nick);
    

    acptr = FindUser(nick);
    if (acptr && !IsServer(acptr)) {
      found++;
      do_whois(sptr, acptr, parc);
    }

    if (!found)
      send_reply(sptr, ERR_NOSUCHNICK, nick);
      
    total+=found;
      
    if (total >= MAX_WHOIS_LINES) {
      send_reply(sptr, ERR_QUERYTOOLONG, parv[1]);
      break;
    }
      
    if (p)
      p[-1] = ',';
  } /* of tokenised parm[1] */
  send_reply(sptr, RPL_ENDOFWHOIS, parv[1]);

  return 0;
}
Esempio n. 11
0
/*
 * ms_rping - server message handler
 * -- by Run
 *
 *    parv[0] = sender (sptr->name thus)
 * if sender is a person: (traveling towards start server)
 *    parv[1] = pinged server[mask]
 *    parv[2] = start server (current target)
 *    parv[3] = optional remark
 * if sender is a server: (traveling towards pinged server)
 *    parv[1] = pinged server (current target)
 *    parv[2] = original sender (person)
 *    parv[3] = start time in s
 *    parv[4] = start time in us
 *    parv[5] = the optional remark
 */
int ms_rping(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  struct Client* destination = 0;
  assert(0 != cptr);
  assert(0 != sptr);
  assert(IsServer(cptr));

  /*
   * shouldn't happen
   */
  if (!IsPrivileged(sptr))
    return 0;

  if (IsServer(sptr)) {
    if (parc < 6) {
      /*
       * PROTOCOL ERROR
       */
      return need_more_params(sptr, "RPING");
    }
    if ((destination = FindNServer(parv[1]))) {
      /*
       * if it's not for me, pass it on
       */
      if (IsMe(destination))
	sendcmdto_one(&me, CMD_RPONG, sptr, "%s %s %s %s :%s", cli_name(sptr),
		      parv[2], parv[3], parv[4], parv[5]);
      else
	sendcmdto_one(sptr, CMD_RPING, destination, "%C %s %s %s :%s",
		      destination, parv[2], parv[3], parv[4], parv[5]);
    }
  }
  else {
    if (parc < 3) {
      return need_more_params(sptr, "RPING");
    }
    /*
     * Haven't made it to the start server yet, if I'm not the start server
     * pass it on.
     */
    if (hunt_server_cmd(sptr, CMD_RPING, cptr, 1, "%s %C :%s", 2, parc, parv)
	!= HUNTED_ISME)
      return 0;
    /*
     * otherwise ping the destination from here
     */
    if ((destination = find_match_server(parv[1]))) {
      assert(IsServer(destination) || IsMe(destination));
      sendcmdto_one(&me, CMD_RPING, destination, "%C %C %s :%s", destination,
		    sptr, militime(0, 0), parv[3]);
    }
    else
      send_reply(sptr, ERR_NOSUCHSERVER, parv[1]);
  }
  return 0;
}
Esempio n. 12
0
/** Handle an ADMIN message from an oper's connection.
 *
 * \a parv has the following elements:
 * \li \a parv[1] (optional) is the server name being interrogated.
 *
 * See @ref m_functions for discussion of the arguments.
 * @param[in] cptr Client that sent us the message.
 * @param[in] sptr Original source of message.
 * @param[in] parc Number of arguments.
 * @param[in] parv Argument vector.
 */
int mo_admin(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  assert(0 != cptr);
  assert(cptr == sptr);

  if (hunt_server_cmd(sptr, CMD_ADMIN, cptr, feature_int(FEAT_HIS_REMOTE), 
                      ":%C", 1, parc, parv) != HUNTED_ISME)
    return 0;
  return send_admin_info(sptr);
}
Esempio n. 13
0
/*
 * m_time - generic message handler
 *
 * parv[0] = sender prefix
 * parv[1] = servername
 */
int m_time(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  if (hunt_server_cmd(sptr, CMD_TIME, cptr, feature_int(FEAT_HIS_REMOTE), ":%C",
                      1, parc, parv)
      != HUNTED_ISME)
    return 0;

  send_reply(sptr, RPL_TIME, cli_name(&me), TStime(), TSoffset, date((long)0));
  return 0;
}
Esempio n. 14
0
/*
 * m_whowas - generic message handler
 *
 * parv[0] = sender prefix
 * parv[1] = nickname queried
 * parv[2] = maximum returned items (optional, default is unlimited)
 * parv[3] = remote server target (Opers only, max returned items 20)
 */
int m_whowas(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
    struct Whowas *temp;
    int cur = 0;
    int max = -1, found = 0;
    char *p, *nick, *s;

    if (parc < 2)
    {
        send_reply(sptr, ERR_NONICKNAMEGIVEN);
        return 0;
    }
    if (parc > 2)
        max = atoi(parv[2]);
    if (parc > 3)
        if (hunt_server_cmd(sptr, CMD_WHOWAS, cptr, 1, "%s %s :%C", 3, parc, parv))
            return 0;

    parv[1] = canonize(parv[1]);
    if (!MyConnect(sptr) && (max > 20))
        max = 20;                   /* Set max replies at 20 */
    for (s = parv[1]; (nick = ircd_strtok(&p, s, ",")); s = 0)
    {
        /* Search through bucket, finding all nicknames that match */
        found = 0;
        for (temp = whowashash[hash_whowas_name(nick)]; temp; temp = temp->hnext)
        {
            if (0 == ircd_strcmp(nick, temp->name))
            {
                send_reply(sptr, RPL_WHOWASUSER, temp->name, temp->username,
                           temp->hostname, temp->realname);
                if (IsAnOper(sptr) && temp->realhost)
                    send_reply(sptr, RPL_WHOISACTUALLY, temp->name, temp->username, temp->realhost, "<untracked>");
                send_reply(sptr, RPL_WHOISSERVER, temp->name,
                           (feature_bool(FEAT_HIS_WHOIS_SERVERNAME) && !IsOper(sptr)) ?
                           feature_str(FEAT_HIS_SERVERNAME) :
                           temp->servername,
                           myctime(temp->logoff));
                if (temp->away)
                    send_reply(sptr, RPL_AWAY, temp->name, temp->away);
                cur++;
                found++;
            }
            if (max >= 0 && cur >= max)
                break;
        }
        if (!found)
            send_reply(sptr, ERR_WASNOSUCHNICK, nick);
        /* To keep parv[1] intact for ENDOFWHOWAS */
        if (p)
            p[-1] = ',';
    }
    send_reply(sptr, RPL_ENDOFWHOWAS, parv[1]);
    return 0;
}
Esempio n. 15
0
/*
 * m_rules - generic message handler
 *
 * parv[0] - sender prefix
 * parv[1] - servername
 */
int m_rules(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  if (!feature_bool(FEAT_RULES))
    return send_reply(sptr, ERR_DISABLED, "RULES");

  if (hunt_server_cmd(sptr, CMD_RULES, cptr, feature_int(FEAT_HIS_REMOTE), "%C", 1,
		      parc, parv) != HUNTED_ISME)
    return 0;

  return motd_send_type(sptr, MOTD_RULES);
}
Esempio n. 16
0
/** Handle an ADMIN message from a server connection.
 *
 * \a parv has the following elements:
 * \li \a parv[1] is the server name being interrogated.
 *
 * See @ref m_functions for discussion of the arguments.
 * @param[in] cptr Client that sent us the message.
 * @param[in] sptr Original source of message.
 * @param[in] parc Number of arguments.
 * @param[in] parv Argument vector.
 */
int ms_admin(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  assert(0 != cptr);
  assert(0 != sptr);

  if (parc < 2)
    return 0;

  if (hunt_server_cmd(sptr, CMD_ADMIN, cptr, 0, ":%C", 1, parc, parv) != HUNTED_ISME)
    return 0;

  return send_admin_info(sptr);
}
Esempio n. 17
0
/** Handle a STATS message from some connection.
 *
 * \a parv has the following elements:
 * \li \a parv[1] is the statistics selector
 * \li \a parv[2] (optional) is server to query
 * \li \a parv[3] (optional) is a mask to filter the results
 *
 * If \a parv[1] is "l" (or "links"), \a parv[3] is a mask of servers.
 * If \a parv[1] is "p" (or "P" or "ports"), \a parv[3] is a mask of
 * ports.  If \a parv[1] is "k" (or "K" or "klines" or "i" or "I" or
 * "access"), \a parv[3] is a hostname with optional username@ prefix
 * (for opers, hostmasks are allowed).
 *
 * See @ref m_functions for discussion of the arguments.
 * @param[in] cptr Client that sent us the message.
 * @param[in] sptr Original source of message.
 * @param[in] parc Number of arguments.
 * @param[in] parv Argument vector.
 */
int
m_stats(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  const struct StatDesc *sd;
  char *param;

  /* If we didn't find a descriptor, send them help */
  if ((parc < 2) || !(sd = stats_find(parv[1])))
      parv[1] = "*", sd = stats_find("*");

  assert(sd != 0);

  /* Check whether the client can issue this command.  If source is
   * not privileged (server or an operator), then the STAT_FLAG_OPERONLY
   * flag must not be set, and if the STAT_FLAG_OPERFEAT flag is set,
   * then the feature given by sd->sd_control must be off.
   *
   * This checks cptr rather than sptr so that a local oper may send
   * /stats queries to other servers.
   */
  if (!IsPrivileged(cptr) &&
      ((sd->sd_flags & STAT_FLAG_OPERONLY) ||
       ((sd->sd_flags & STAT_FLAG_OPERFEAT) && feature_bool(sd->sd_control))))
    return send_reply(sptr, ERR_NOPRIVILEGES);

  /* Check for extra parameter */
  if ((sd->sd_flags & STAT_FLAG_VARPARAM) && parc > 3 && !EmptyString(parv[3]))
    param = parv[3];
  else
    param = NULL;

  /* Ok, track down who's supposed to get this... */
  if (hunt_server_cmd(sptr, CMD_STATS, cptr, feature_int(FEAT_HIS_REMOTE),
		      param ? "%s %C :%s" : "%s :%C", 2, parc, parv) !=
      HUNTED_ISME)
    return 0; /* Someone else--cool :) */

  /* Check if they are a local user */
  if ((sd->sd_flags & STAT_FLAG_LOCONLY) && !MyUser(sptr))
    return send_reply(sptr, ERR_NOPRIVILEGES);

  assert(sd->sd_func != 0);

  /* Ok, dispatch the stats function */
  (*sd->sd_func)(sptr, sd, param);

  /* Done sending them the stats */
  return send_reply(sptr, RPL_ENDOFSTATS, parv[1]);
}
Esempio n. 18
0
/*
 * ms_uping - server message handler
 *
 * m_uping  -- by Run
 *
 * parv[0] = sender prefix
 * parv[1] = pinged server
 * parv[2] = port
 * parv[3] = hunted server
 * parv[4] = number of requested pings
 */
int ms_uping(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  struct ConfItem *aconf;
  int port;
  int count;

  assert(0 != cptr);
  assert(0 != sptr);

  if (!IsAnOper(sptr)) {
    send_reply(sptr, ERR_NOPRIVILEGES);
    return 0;
  }

  if (parc < 5) {
    send_reply(sptr, ERR_NEEDMOREPARAMS, "UPING");
    return 0;
  }

  if (hunt_server_cmd(sptr, CMD_UPING, cptr, 1, "%s %s %C %s", 3, parc, parv)
      != HUNTED_ISME)
    return 0;
  /*
   * Determine port: First user supplied, then default : 7007
   */
  if (EmptyString(parv[2]) || (port = atoi(parv[2])) <= 0)
    port = atoi(UDP_PORT);

  if (EmptyString(parv[4]) || (count = atoi(parv[4])) <= 0)
  {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :UPING : Illegal number of "
		  "packets: %s", sptr, parv[4]);
    return 0;
  }
  /* 
   * Check if a CONNECT would be possible at all (adapted from m_connect)
   */
  if ((aconf = conf_find_server(parv[1])))
    uping_server(sptr, aconf, port, count);
  else
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :UPING: Host %s not listed in "
		  "ircd.conf", sptr, parv[1]);

  return 0;
}
Esempio n. 19
0
/*
 * m_copyright - generic message handler
 *
 * parv[0] - sender prefix
 * parv[1] - servername
 *
 */
int m_copyright(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  const char **text = copyrighttext;

  if (hunt_server_cmd(sptr, CMD_COPYRIGHT, cptr, 1, ":%C", 1, parc, parv)
      != HUNTED_ISME)
    return 0;

  while (text[0])
  {
    send_reply(sptr, RPL_INFO, *text);
    text++;
  }

  send_reply(sptr, RPL_INFO, "");
  send_reply(sptr, RPL_ENDOFINFO);

  return 0;
}
Esempio n. 20
0
/*
 * mo_rping - oper message handler
 * -- by Run
 *
 *
 * Receive:
 *          RPING blah.*
 *          RPING blah.* :<start time>
 *          RPING blah.* server.* :<start time>
 *
 *    parv[0] = sender (sptr->name thus)
 *    parv[1] = pinged server name or mask (required)
 *    parv[2] = start server name or mask (optional, defaults to me)
 *    parv[3] = client start time (optional) 
 * 
 * Send: NumNick(sptr) RPING blah.* server.net :<start time> (hunt_server)
 *       NumServ(&me) RPING NumServ(blah.bar.net) NumNick(sptr) :<start time> (here)
 */
int mo_rping(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  struct Client* acptr = 0;
  const char*    start_time = "<No client start time>";

  assert(0 != cptr);
  assert(0 != sptr);
  assert(cptr == sptr);
  assert(IsAnOper(sptr));

  if (parc < 2)
    return need_more_params(sptr, "RPING");

  if (parc > 2) {
    if ((acptr = find_match_server(parv[2])) && !IsMe(acptr)) {
      parv[2] = cli_name(acptr);
      if (3 == parc) {
        /*
         * const_cast<char*>(start_time);
         */
        parv[parc++] = (char*) start_time;
      }
      hunt_server_cmd(sptr, CMD_RPING, cptr, 1, "%s %C :%s", 2, parc, parv);
      return 0;
    }
    else
      start_time = parv[2];
  }

  if ((acptr = find_match_server(parv[1]))) {
    assert(IsServer(acptr) || IsMe(acptr));
    sendcmdto_one(&me, CMD_RPING, acptr, "%C %C %s :%s", acptr, sptr,
		  militime(0, 0), start_time);
  }
  else
    send_reply(sptr, ERR_NOSUCHSERVER, parv[1]);

  return 0;
}
Esempio n. 21
0
/*
 * m_links - generic message handler
 *
 * parv[0] = sender prefix
 * parv[1] = servername mask
 *
 * or
 *
 * parv[0] = sender prefix
 * parv[1] = server to query
 * parv[2] = servername mask
 */
int m_links(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  char *mask;
  struct Client *acptr;

  if (feature_bool(FEAT_HIS_LINKS) && !IsAnOper(sptr))
  {
    send_reply(sptr, RPL_ENDOFLINKS, parc < 2 ? "*" : parv[1]);
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :%s %s", sptr,
                  "/LINKS has been disabled, from CFV-165.  Visit ", 
                  feature_str(FEAT_HIS_URLSERVERS));
    return 0;
  }

  if (parc > 2)
  {
    if (hunt_server_cmd(sptr, CMD_LINKS, cptr, 1, "%C :%s", 1, parc, parv) !=
        HUNTED_ISME)
      return 0;
    mask = parv[2];
  }
  else
    mask = parc < 2 ? 0 : parv[1];

  for (acptr = GlobalClientList, collapse(mask); acptr; acptr = cli_next(acptr))
  {
    if (!IsServer(acptr) && !IsMe(acptr))
      continue;
    if (!BadPtr(mask) && match(mask, cli_name(acptr)))
      continue;
    send_reply(sptr, RPL_LINKS, cli_name(acptr), cli_name(cli_serv(acptr)->up),
        cli_hopcount(acptr), cli_serv(acptr)->prot,
        ((cli_info(acptr))[0] ? cli_info(acptr) : "(Unknown Location)"));
  }

  send_reply(sptr, RPL_ENDOFLINKS, BadPtr(mask) ? "*" : mask);

  return 0;
}
Esempio n. 22
0
/*
 * mo_version - oper message handler
 *
 *   parv[0] = sender prefix
 *   parv[1] = servername
 */
int mo_version(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  struct Client *acptr;

  if (MyConnect(sptr) && parc > 1)
  {
    if (!(acptr = find_match_server(parv[1])))
    {
      send_reply(sptr, ERR_NOSUCHSERVER, parv[1]);
      return 0;
    }
    parv[1] = cli_name(acptr);
  }

  if (hunt_server_cmd(sptr, CMD_VERSION, cptr, feature_int(FEAT_HIS_REMOTE),
                                                           ":%C", 1,
                                                           parc, parv)
                      == HUNTED_ISME)
  {
    send_reply(sptr, RPL_VERSION, version, cvs_version, debugmode, cli_name(&me),
	       debug_serveropts());
#ifdef USE_SSL
#ifdef DEBUGMODE
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Headers: %s", sptr, OPENSSL_VERSION_TEXT);
#endif
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Library: %s", sptr, SSLeay_version(SSLEAY_VERSION));
#endif
#ifdef USE_GEOIP
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :GeoIP %s", sptr, geoip_version());
#endif
#ifdef USE_MMDB
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :MaxMindDB %s", sptr, geoip_libmmdb_version());
#endif
    send_supported(sptr);
  }

  return 0;
}
Esempio n. 23
0
static
void do_trace(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
{
    int i;
    struct Client *acptr;
    struct Client *acptr2;
    const struct ConnectionClass* cl;
    char* tname;
    int doall;
    int *link_s;
    int *link_u;
    int cnt = 0;
    int wilds;
    int dow;

    if (parc < 2 || BadPtr(parv[1]))
    {
        /* just "TRACE" without parameters. Must be from local client */
        parc = 1;
        acptr = &me;
        tname = cli_name(&me);
        i = HUNTED_ISME;
    }
    else if (parc < 3 || BadPtr(parv[2]))
    {
        /* No target specified. Make one before propagating. */
        parc = 2;
        tname = parv[1];
        if ((acptr = find_match_server(parv[1])) ||
                ((acptr = FindClient(parv[1])) && !MyUser(acptr)))
        {
            if (IsUser(acptr))
                parv[2] = cli_name(cli_user(acptr)->server);
            else
                parv[2] = cli_name(acptr);
            parc = 3;
            parv[3] = 0;
            if ((i = hunt_server_cmd(sptr, CMD_TRACE, cptr, IsServer(acptr),
                                     "%s :%C", 2, parc, parv)) == HUNTED_NOSUCH)
                return;
        }
        else
            i = HUNTED_ISME;
    } else {
        /* Got "TRACE <tname> :<target>" */
        parc = 3;
        if (MyUser(sptr) || Protocol(cptr) < 10)
            acptr = find_match_server(parv[2]);
        else
            acptr = FindNServer(parv[2]);
        if ((i = hunt_server_cmd(sptr, CMD_TRACE, cptr, 0, "%s :%C", 2, parc,
                                 parv)) == HUNTED_NOSUCH)
            return;
        tname = parv[1];
    }

    if (i == HUNTED_PASS) {
        if (!acptr)
            acptr = next_client(GlobalClientList, tname);
        else
            acptr = cli_from(acptr);
        send_reply(sptr, RPL_TRACELINK,
                   version, debugmode, tname,
                   acptr ? cli_name(cli_from(acptr)) : "<No_match>");
        return;
    }

    doall = (parv[1] && (parc > 1)) ? !match(tname, cli_name(&me)) : 1;
    wilds = !parv[1] || strchr(tname, '*') || strchr(tname, '?');
    dow = wilds || doall;

    /* Don't give (long) remote listings to lusers */
    if (dow && !MyConnect(sptr) && !IsAnOper(sptr)) {
        send_reply(sptr, RPL_TRACEEND);
        return;
    }

    link_s = MyCalloc(2 * maxconnections, sizeof(link_s[0]));
    link_u = link_s + maxconnections;

    if (doall) {
        for (acptr = GlobalClientList; acptr; acptr = cli_next(acptr)) {
            if (IsUser(acptr))
                link_u[cli_fd(cli_from(acptr))]++;
            else if (IsServer(acptr))
                link_s[cli_fd(cli_from(acptr))]++;
        }
    }

    /* report all direct connections */

    for (i = 0; i <= HighestFd; i++) {
        const char *conClass;

        if (!(acptr = LocalClientArray[i])) /* Local Connection? */
            continue;
        if (IsInvisible(acptr) && dow && !(MyConnect(sptr) && IsOper(sptr)) &&
                !IsAnOper(acptr) && (acptr != sptr))
            continue;
        if (!doall && wilds && match(tname, cli_name(acptr)))
            continue;
        if (!dow && 0 != ircd_strcmp(tname, cli_name(acptr)))
            continue;

        conClass = get_client_class(acptr);

        switch (cli_status(acptr)) {
        case STAT_CONNECTING:
            send_reply(sptr, RPL_TRACECONNECTING, conClass, cli_name(acptr));
            cnt++;
            break;
        case STAT_HANDSHAKE:
            send_reply(sptr, RPL_TRACEHANDSHAKE, conClass, cli_name(acptr));
            cnt++;
            break;
        case STAT_ME:
            break;
        case STAT_UNKNOWN:
        case STAT_UNKNOWN_USER:
            send_reply(sptr, RPL_TRACEUNKNOWN, conClass,
                       get_client_name(acptr, HIDE_IP));
            cnt++;
            break;
        case STAT_UNKNOWN_SERVER:
            send_reply(sptr, RPL_TRACEUNKNOWN, conClass, "Unknown Server");
            cnt++;
            break;
        case STAT_USER:
            /* Only opers see users if there is a wildcard
               but anyone can see all the opers. */
            if ((IsAnOper(sptr) && (MyUser(sptr) ||
                                    !(dow && IsInvisible(acptr)))) || !dow || IsAnOper(acptr)) {
                if (IsAnOper(acptr))
                    send_reply(sptr, RPL_TRACEOPERATOR, conClass,
                               get_client_name(acptr, SHOW_IP),
                               CurrentTime - cli_lasttime(acptr));
                else
                    send_reply(sptr, RPL_TRACEUSER, conClass,
                               get_client_name(acptr, SHOW_IP),
                               CurrentTime - cli_lasttime(acptr));
                cnt++;
            }
            break;
        /*
         * Connection is a server
         *
         * Serv <class> <nS> <nC> <name> <ConnBy> <last> <age>
         *
         * class        Class the server is in
         * nS           Number of servers reached via this link
         * nC           Number of clients reached via this link
         * name         Name of the server linked
         * ConnBy       Who established this link
         * last         Seconds since we got something from this link
         * age          Seconds this link has been alive
         *
         * Additional comments etc......        -Cym-<*****@*****.**>
         */

        case STAT_SERVER:
            if (cli_serv(acptr)->user) {
                if (!cli_serv(acptr)->by[0]
                        || !(acptr2 = findNUser(cli_serv(acptr)->by))
                        || (cli_user(acptr2) != cli_serv(acptr)->user))
                    acptr2 = NULL;
                send_reply(sptr, RPL_TRACESERVER, conClass, link_s[i],
                           link_u[i], cli_name(acptr),
                           acptr2 ? cli_name(acptr2) : "*",
                           cli_serv(acptr)->user->username,
                           cli_serv(acptr)->user->host,
                           CurrentTime - cli_lasttime(acptr),
                           CurrentTime - cli_serv(acptr)->timestamp);
            } else
                send_reply(sptr, RPL_TRACESERVER, conClass, link_s[i],
                           link_u[i], cli_name(acptr),
                           (*(cli_serv(acptr))->by) ?  cli_serv(acptr)->by : "*", "*",
                           cli_name(&me), CurrentTime - cli_lasttime(acptr),
                           CurrentTime - cli_serv(acptr)->timestamp);
            cnt++;
            break;
        default:                  /* We actually shouldn't come here, -msa */
            send_reply(sptr, RPL_TRACENEWTYPE, get_client_name(acptr, HIDE_IP));
            cnt++;
            break;
        }
    }
    /*
     * Add these lines to summarize the above which can get rather long
     * and messy when done remotely - Avalon
     */
    if (IsAnOper(sptr) && doall) {
        for (cl = get_class_list(); cl; cl = cl->next) {
            if (Links(cl) > 1)
                send_reply(sptr, RPL_TRACECLASS, ConClass(cl), Links(cl) - 1);
        }
    }
    send_reply(sptr, RPL_TRACEEND);
    MyFree(link_s);
}
Esempio n. 24
0
/** Handle a CONNECT message from a server.
 *
 * \a parv has the following elements:
 * \li \a parv[1] is the server that should initiate the connection
 * \li \a parv[2] is the port number to connect on (zero for the default)
 * \li \a parv[3] is the server to connect to
 *
 * See @ref m_functions for discussion of the arguments.
 * @param[in] cptr Client that sent us the message.
 * @param[in] sptr Original source of message.
 * @param[in] parc Number of arguments.
 * @param[in] parv Argument vector.
 */
int ms_connect(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  unsigned short   port;
  unsigned short   tmpport;
  const char*      rule;
  struct ConfItem* aconf;
  struct Client*   acptr;
  struct Jupe*     ajupe;

  assert(0 != cptr);
  assert(0 != sptr);

  if (!IsPrivileged(sptr))
    return send_reply(sptr, ERR_NOPRIVILEGES);

  if (parc < 4) {
    /*
     * this is coming from a server which should have already
     * checked it's args, if we don't have parc == 4, something
     * isn't right.
     */
    protocol_violation(sptr, "Too few parameters to connect");
    return need_more_params(sptr, "CONNECT");
  }

  if (hunt_server_cmd(sptr, CMD_CONNECT, cptr, 1, "%s %s :%C", 3, parc, parv)
      != HUNTED_ISME)
    return 0;

  /*
   * need to find the conf entry first so we can use the server name from
   * the conf entry instead of parv[1] to find out if the server is already
   * present below. --Bleep
   */
  if (0 == (aconf = conf_find_server(parv[1]))) {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Connect: Host %s not listed "
		  "in ircd.conf", sptr, parv[1]);
    return 0;
  }
  /*
   * use aconf->name to look up the server
   */
  if ((acptr = FindServer(aconf->name))) {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Connect: Server %s already "
		  "exists from %s", sptr, parv[1], cli_name(cli_from(acptr)));
    return 0;
  }
  /*
   * Evaluate connection rules...  If no rules found, allow the
   * connect.   Otherwise stop with the first true rule (ie: rules
   * are ored together.  Oper connects are effected only by D
   * lines (CRULEALL) not d lines (CRULEAUTO).
   */
  if ((rule = conf_eval_crule(aconf->name, CRULE_ALL))) {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Connect: Disallowed by rule: %s", sptr, rule);
    return 0;
  }
  /*
   * Check to see if the server is juped; if it is, disallow the connect
   */
  if ((ajupe = jupe_find(aconf->name)) && JupeIsActive(ajupe)) {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Connect: Server %s is juped: %s",
		  sptr, JupeServer(ajupe), JupeReason(ajupe));
    return 0;
  }

  /*
   * Allow opers to /connect foo.* 0 bah.* to connect foo and bah
   * using the conf's configured port
   */
  port = atoi(parv[2]);
  /*
   * save the old port
   */
  tmpport = aconf->address.port;
  if (port)
    aconf->address.port = port;
  else
    port = aconf->address.port;

  /*
   * Notify all operators about remote connect requests
   */
  sendwallto_group(&me, WALL_WALLOPS, 0,
                   "Remote CONNECT %s %s from %s", parv[1],
                   parv[2] ? parv[2] : "",
                   get_client_name(sptr, HIDE_IP));
  log_write(LS_NETWORK, L_INFO, 0, "CONNECT From %C : %s %s", sptr, parv[1],
	    parv[2] ? parv[2] : "");

  if (connect_server(aconf, sptr)) {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :*** Connecting to %s.", sptr,
		  aconf->name);
  }
  else {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :*** Connection to %s failed",
		  sptr, aconf->name);
  }
  aconf->address.port = tmpport;
  return 0;
}
Esempio n. 25
0
/** Handle a CONNECT message from an operator.
 *
 * \a parv has the following elements:
 * \li \a parv[1] is the server that should initiate the connection
 * \li \a parv[2] is the port number to connect on (zero for the default)
 * \li \a parv[3] is the server to connect to
 *
 * See @ref m_functions for discussion of the arguments.
 * @param[in] cptr Client that sent us the message.
 * @param[in] sptr Original source of message.
 * @param[in] parc Number of arguments.
 * @param[in] parv Argument vector.
 */
int mo_connect(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  unsigned short   port;
  unsigned short   tmpport;
  const char*      rule;
  struct ConfItem* aconf;
  struct Client*   acptr;
  struct Jupe*     ajupe;

  assert(0 != cptr);
  assert(cptr == sptr);
  assert(IsAnOper(sptr));

  if (parc < 2)
    return need_more_params(sptr, "CONNECT");

  if (parc > 3) {
    /*
     * if parc > 3, we are trying to connect two remote
     * servers to each other
     */
    if (IsLocOp(sptr)) {
      /*
       * Only allow LocOps to make local CONNECTS --SRB
       */
      return send_reply(cptr, ERR_NOPRIVILEGES);
    }
    else {
      struct Client* acptr2;
      struct Client* acptr3;

      if (!(acptr3 = find_match_server(parv[3]))) {
        return send_reply(sptr, ERR_NOSUCHSERVER, parv[3]);
      }

      /*
       * Look for closest matching server 
       * needed for "/connect blah 4400 *"?
       */
      for (acptr2 = acptr3; acptr2 != &me; acptr2 = cli_serv(acptr2)->up) {
        if (!match(parv[3], cli_name(acptr2)))
          acptr3 = acptr2;
      }
      parv[3] = cli_name(acptr3);
      if (hunt_server_cmd(sptr, CMD_CONNECT, cptr, 1, "%s %s :%C", 3, parc,
			  parv) != HUNTED_ISME)
        return 0;
    }
  }
  /*
   * need to find the conf entry first so we can use the server name from
   * the conf entry instead of parv[1] to find out if the server is already
   * present below. --Bleep
   */
  if (0 == (aconf = conf_find_server(parv[1]))) {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Connect: Host %s not listed "
		  "in ircd.conf", sptr, parv[1]);
    return 0;
  }
  /*
   * use aconf->name to look up the server, see above
   */
  if ((acptr = FindServer(aconf->name))) {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Connect: Server %s already "
		  "exists from %s", sptr, parv[1], cli_name(cli_from(acptr)));
    return 0;
  }
  /*
   * Evaluate connection rules...  If no rules found, allow the
   * connect.   Otherwise stop with the first true rule (ie: rules
   * are ored together.  Oper connects are effected only by D
   * lines (CRULEALL) not d lines (CRULEAUTO).
   */
  if ((rule = conf_eval_crule(aconf->name, CRULE_ALL))) {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Connect: Disallowed by rule: %s", sptr, rule);
    return 0;
  }
  /*
   * Check to see if the server is juped; if it is, disallow the connect
   */
  if ((ajupe = jupe_find(aconf->name)) && JupeIsActive(ajupe)) {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Connect: Server %s is juped: %s",
		  sptr, JupeServer(ajupe), JupeReason(ajupe));
    return 0;
  }
  /*
   *  Get port number from user, if given. If not specified,
   *  use the default from configuration structure. If missing
   *  from there, then use the precompiled default.
   */
  port = aconf->address.port;
  if (parc > 2) {
    assert(0 != parv[2]);
    if (0 == (port = atoi(parv[2]))) {
      sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Connect: Invalid port number",
		    sptr);
      return 0;
    }
  }
  if (0 == port && 0 == (port = feature_int(FEAT_SERVER_PORT))) {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Connect: missing port number",
		  sptr);
    return 0;
  }

  tmpport = aconf->address.port;
  aconf->address.port = port;

  if (connect_server(aconf, sptr)) {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :*** Connecting to %s.", sptr,
		  aconf->name);
  }
  else {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :*** Connection to %s failed",
		  sptr, aconf->name);
  }
  aconf->address.port = tmpport;
  return 0;
}
Esempio n. 26
0
/*
 * m_whois - generic message handler
 *
 * parv[0] = sender prefix
 * parv[1] = nickname masklist
 *
 * or
 *
 * parv[1] = target server, or a nickname representing a server to target.
 * parv[2] = nickname masklist
 */
int m_whois(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  char*           nick;
  char*           tmp;
  char*           p = 0;
  int             found = 0;
  int		  total = 0;
  int             wildscount = 0;

  if (parc < 2)
  {
    send_reply(sptr, ERR_NONICKNAMEGIVEN);
    return 0;
  }

  if (parc > 2)
  {
    /* For convenience: Accept a nickname as first parameter, by replacing
     * it with the correct servername - as is needed by hunt_server().
     * This is the secret behind the /whois nick nick trick.
     */
    if (feature_int(FEAT_HIS_REMOTE))
    {
      /* If remote queries are disabled, then use the *second* parameter of
       * of whois, so /whois nick nick still works.
       */
      if (!IsAnOper(sptr))
      {
        if (!FindUser(parv[2]))
        {
          send_reply(sptr, ERR_NOSUCHNICK, parv[2]);
          send_reply(sptr, RPL_ENDOFWHOIS, parv[2]);
          return 0;
        }
        parv[1] = parv[2];
      }
    }

    if (hunt_server_cmd(sptr, CMD_WHOIS, cptr, 0, "%C :%s", 1, parc, parv) !=
       HUNTED_ISME)
    return 0;
    
    parv[1] = parv[2];
  }

  for (tmp = parv[1]; (nick = ircd_strtok(&p, tmp, ",")); tmp = 0)
  {
    int wilds;

    found = 0;
    
    collapse(nick);
    
    wilds = (strchr(nick, '?') || strchr(nick, '*'));
    if (!wilds) {
      struct Client *acptr = 0;
      /* No wildcards */
      acptr = FindUser(nick);
      if (acptr && !IsServer(acptr)) {
        do_whois(sptr, acptr, parc);
        found = 1;
      }
    }
    else /* wilds */
    {
      if (++wildscount > 3) {
        send_reply(sptr, ERR_QUERYTOOLONG, parv[1]);
        break;
      }
      found=do_wilds(sptr, nick, total, parc);
    }

    if (!found)
      send_reply(sptr, ERR_NOSUCHNICK, nick);
    total+=found;
    if (total >= MAX_WHOIS_LINES) {
      send_reply(sptr, ERR_QUERYTOOLONG, parv[1]);
      break;
    }
    if (p)
      p[-1] = ',';
  } /* of tokenised parm[1] */
  send_reply(sptr, RPL_ENDOFWHOIS, parv[1]);

  return 0;
}
Esempio n. 27
0
int m_names(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  struct Channel *chptr; 
  struct Channel *ch2ptr; 
  struct Client *c2ptr;
  struct Membership* member; 
  char* s;
  char* para = parc > 1 ? parv[1] : 0; 
  int showingdelayed = 0;

  if (parc > 1 && !ircd_strcmp(parv[1], "-D")) {
    para = (parc > 2) ? parv[2] : 0;
    showingdelayed = NAMES_DEL;
    if (parc > 3 && hunt_server_cmd(sptr, CMD_NAMES, cptr, 1, "%s %s %C", 3, parc, parv))
      return 0;
  } else if (parc > 2 && hunt_server_cmd(sptr, CMD_NAMES, cptr, 1, "%s %C", 2, parc, parv))
    return 0;

  if (EmptyString(para)) {
    send_reply(sptr, RPL_ENDOFNAMES, "*");
    return 0;
  }

  do {
    s = strchr(para, ',');
    if (s)
      *s++ = '\0';
    /*
     * Special Case 1: "/names 0". 
     * Full list as per RFC. 
     */
    if ((*para == '0') || (*para == '\0'))
    {
      int idx; 
      int mlen;
      int flag;
      struct Channel *ch3ptr;
      char buf[BUFSIZE]; 

      mlen = strlen(cli_name(&me)) + 10 + strlen(cli_name(sptr));

      /* List all visible channels/visible members */ 

      for (ch2ptr = GlobalChannelList; ch2ptr; ch2ptr = ch2ptr->next)
      { 
        if (!ShowChannel(sptr, ch2ptr))
          continue;                 /* Don't show secret chans. */ 
        else if (find_channel_member(sptr, ch2ptr))
          do_names(sptr, ch2ptr, showingdelayed|NAMES_ALL); /* Full list if we're in this chan. */
        else
          do_names(sptr, ch2ptr, showingdelayed|NAMES_VIS);
      } 

      /* List all remaining users on channel '*' */

      strcpy(buf, "* * :");
      idx = 5;
      flag = 0;

      for (c2ptr = GlobalClientList; c2ptr; c2ptr = cli_next(c2ptr))
      {
        int showflag = 0;

        if (!IsUser(c2ptr) || (sptr != c2ptr && IsInvisible(c2ptr)))
          continue;

        member = cli_user(c2ptr)->channel;

        while (member)
        {
          ch3ptr = member->channel;
  
          if (PubChannel(ch3ptr) || find_channel_member(sptr, ch3ptr))
            showflag = 1;
 
          member = member->next_channel;
        }

        if (showflag)               /* Have we already shown them? */
          continue;
 
        strcpy(buf + idx, cli_name(c2ptr));
        idx += strlen(cli_name(c2ptr));
        buf[idx++] = ' ';
        flag = 1;

        if (mlen + idx + NICKLEN + 3 > BUFSIZE)     /* space, \r\n\0 */
        {
          send_reply(sptr, RPL_NAMREPLY, buf);
          strcpy(buf, "* * :");
          idx = 5;
          flag = 0;
        }
      }
      if (flag)
        send_reply(sptr, RPL_NAMREPLY, buf);
      send_reply(sptr, RPL_ENDOFNAMES, "*");
    }
    else if ((chptr = FindChannel(para)) != NULL)
    {
      member = find_member_link(chptr, sptr);
      if (member)
      {
        /*
         *  Special Case 2: User is on this channel, requesting full names list.
         *  (As performed with each /join) - ** High frequency usage **
         */
        do_names(sptr, chptr, showingdelayed|NAMES_ALL|NAMES_EON);
      }
      else
      {
        /*
         *  Special Case 3: User isn't on this channel, show all visible users, in 
         *  non secret channels.
         */ 
        do_names(sptr, chptr, showingdelayed|NAMES_VIS|NAMES_EON);
      } 
    }
    else
        send_reply(sptr, RPL_ENDOFNAMES, para);
  } while ((para = s) != NULL);

  return 1;
}
Esempio n. 28
0
/*
 * Syntax: CHECK <channel|nick|server|hostmask> [-flags]
 * 
 * Where valid flags are:
 * -c: Show channels when checking a hostmask.
 * -i: Show IPs instead of hostnames when displaying results.
 * -o: Only show channel operators when checking a channel.
 * -u: Hide users when checking a channel.
 * 
 * <hostmask> can be of the form host, user@host, nick!user@host, 
 * with host being host.domain.cc, 127.0.0.1 or 127.0.0.0/24.
 * Wildcards are supported.
 */
int mo_check(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
{
   struct Channel *chptr;
   struct Client *acptr;
   int flags = CHECK_SHOWUSERS, i;


   if (!HasPriv(sptr, PRIV_CHECK))
     return send_reply(sptr, ERR_DISABLED, "CHECK");

   if (parc < 2) {
      send_reply(sptr, ERR_NEEDMOREPARAMS, "CHECK");
      return 0;
   }

   if ( parc>=4 || (parc==3 && parv[2][0] != '-')) {
    /* remote query */
    if (hunt_server_cmd(sptr, CMD_CHECK, cptr, 0, parc==4 ? "%C %s %s" : "%C %s", 1, parc, parv) != HUNTED_ISME)
       return 0;
     parv++; parc--;
   }

   /* This checks to see if any flags have been supplied */
   if ((parc >= 3) && (parv[2][0] == '-')) {
    for (i = 0; parv[2][i]; i++) {
        switch (parv[2][i]) {
       case 'c':
         flags |= CHECK_CHECKCHAN;
         break;
        
       case 'o':
         flags |= CHECK_OPSONLY; /* fall through */
       case 'u':
         flags &= ~(CHECK_SHOWUSERS);
         break;
        
       case 'i':
         flags |= CHECK_SHOWIPS;
         break;
        
       default:
         /* might want to raise some sort of error here? */
         break;
       }
     }
   }

   if (IsChannelName(parv[1]))  /* channel */
   {
      if ((chptr = FindChannel(parv[1])))
      {
         checkChannel(sptr, chptr);
         checkUsers(sptr, chptr, flags);
      }
      else
      {
         send_reply(sptr, ERR_SEARCHNOMATCH, "CHECK", parv[1]);
      }
   }
   else if ((acptr = FindClient(parv[1])) && !(FindServer(parv[1])))  /* client and not a server */
   {
      if (!IsRegistered(acptr))
   	{
         send_reply(sptr, ERR_SEARCHNOMATCH, "CHECK", parv[1]);
         return 0;
      }

    checkClient(sptr, acptr);
   }
   else if ((acptr = FindServer(parv[1]))) { /* server */
     checkServer(sptr, acptr);
   }
   else if (checkHostmask(sptr, parv[1], flags) > 0) /* hostmask */
     return 1;
   else /* no match */
     send_reply(sptr, ERR_SEARCHNOMATCH, "CHECK", parv[1]);

 
  return 1;
}