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

Nick.cpp

/*******************************************************************************
 * shroudBNC - an object-oriented framework for IRC                            *
 * Copyright (C) 2005-2007 Gunnar Beutner                                      *
 *                                                                             *
 * 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 2              *
 * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. *
 *******************************************************************************/

#include "StdAfx.h"

/**
 * CNick
 *
 * Constructs a new nick object.
 *
 * @param Nick the nickname of the user
 * @param Owner the owning channel of this nick object
 */
00030 CNick::CNick(const char *Nick, CChannel *Owner) {
      assert(Nick != NULL);

      SetOwner(Owner);

      m_Nick = ustrdup(Nick);

      CHECK_ALLOC_RESULT(m_Nick, ustrdup) { } CHECK_ALLOC_RESULT_END;

      m_Prefixes = NULL;
      m_Site = NULL;
      m_Realname = NULL;
      m_Server = NULL;
      m_Creation = g_CurrentTime;
      m_IdleSince = m_Creation;
}

/**
 * ~CNick
 *
 * Destroys a nick object.
 */
00052 CNick::~CNick() {
      ufree(m_Nick);
      ufree(m_Prefixes);
      ufree(m_Site);
      ufree(m_Realname);
      ufree(m_Server);

      for (unsigned int i = 0; i < m_Tags.GetLength(); i++) {
            ufree(m_Tags[i].Name);
            ufree(m_Tags[i].Value);
      }
}

/**
 * SetNick
 *
 * Sets the user's nickname.
 *
 * @param Nick the new nickname
 */
00072 bool CNick::SetNick(const char *Nick) {
      char *NewNick;

      assert(Nick != NULL);

      NewNick = ustrdup(Nick);

      CHECK_ALLOC_RESULT(m_Nick, ustrdup) {
            return false;
      } CHECK_ALLOC_RESULT_END;

      ufree(m_Nick);
      m_Nick = NewNick;

      return true;
}

/**
 * GetNick
 *
 * Returns the current nick of the user.
 */
00094 const char *CNick::GetNick(void) const {
      return m_Nick;
}

/**
 * IsOp
 *
 * Returns whether the user is an op.
 */
00103 bool CNick::IsOp(void) const {
      return HasPrefix('@');
}

/**
 * IsVoice
 *
 * Returns whether the user is voiced.
 */
00112 bool CNick::IsVoice(void) const {
      return HasPrefix('+');
}

/**
 * IsHalfop
 *
 * Returns whether the user is a half-op.
 */
00121 bool CNick::IsHalfop(void) const {
      return HasPrefix('%');
}

/**
 * HasPrefix
 *
 * Returns whether the user has the given prefix.
 *
 * @param Prefix the prefix (e.g. @, +)
 */
00132 bool CNick::HasPrefix(char Prefix) const {
      if (m_Prefixes != NULL && strchr(m_Prefixes, Prefix) != NULL) {
            return true;
      } else {
            return false;
      }
}

/**
 * AddPrefix
 *
 * Adds a prefix to a user.
 *
 * @param Prefix the new prefix
 */
00147 bool CNick::AddPrefix(char Prefix) {
      char *Prefixes;
      size_t LengthPrefixes = m_Prefixes ? strlen(m_Prefixes) : 0;

      Prefixes = (char *)urealloc(m_Prefixes, LengthPrefixes + 2);

      CHECK_ALLOC_RESULT(Prefixes, realloc) {
            return false;
      } CHECK_ALLOC_RESULT_END;

      m_Prefixes = Prefixes;
      m_Prefixes[LengthPrefixes] = Prefix;
      m_Prefixes[LengthPrefixes + 1] = '\0';

      return true;
}

/**
 * RemovePrefix
 *
 * Removes the specified prefix from the user.
 *
 * @param Prefix the prefix
 */
00171 bool CNick::RemovePrefix(char Prefix) {
      int a = 0;
      size_t LengthPrefixes;

      if (m_Prefixes == NULL) {
            return true;
      }

      LengthPrefixes = strlen(m_Prefixes);

      char *Copy = (char *)umalloc(LengthPrefixes + 1);

      CHECK_ALLOC_RESULT(Copy, umalloc) {
            return false;
      } CHECK_ALLOC_RESULT_END;

      for (unsigned int i = 0; i < LengthPrefixes; i++) {
            if (m_Prefixes[i] != Prefix) {
                  Copy[a++] = m_Prefixes[i];
            }
      }

      Copy[a] = '\0';

      ufree(m_Prefixes);
      m_Prefixes = Copy;

      return true;
}

/**
 * SetPrefixes
 *
 * Sets the prefixes for a user.
 *
 * @param Prefixes the new prefixes
 */
00208 bool CNick::SetPrefixes(const char *Prefixes) {
      char *dupPrefixes;

      if (Prefixes) {
            dupPrefixes = ustrdup(Prefixes);

            CHECK_ALLOC_RESULT(dupPrefixes, ustrdup) {
                  return false;
            } CHECK_ALLOC_RESULT_END;
      } else {
            dupPrefixes = NULL;
      }

      ufree(m_Prefixes);
      m_Prefixes = dupPrefixes;

      return true;
}

/**
 * GetPrefixes
 *
 * Returns all prefixes for a user.
 */
00232 const char *CNick::GetPrefixes(void) const {
      return m_Prefixes;
}

/**
 * IMPL_NICKSET
 *
 * Implements a Set*() function
 *
 * @param Name the name of the attribute
 * @param NewValue the new value
 * @param Static indicates whether the attribute can be modified
 *            once its initial value has been set
 */
#define IMPL_NICKSET(Name, NewValue, Static) \
      char *DuplicateValue; \
\
      if ((Static && Name != NULL) || NewValue == NULL) { \
            return false; \
      } \
\
      DuplicateValue = ustrdup(NewValue); \
\
      if (DuplicateValue == NULL) { \
            LOGERROR("ustrdup() failed. New " #Name " was lost (%s, %s).", m_Nick, NewValue); \
\
            return false; \
      } else { \
            ufree(Name); \
            Name = DuplicateValue; \
\
            return true; \
      }

/**
 * SetSite
 *
 * Sets the site (ident\@host) for a user.
 *
 * @param Site the user's new site
 */
00273 bool CNick::SetSite(const char *Site) {
      IMPL_NICKSET(m_Site, Site, false);
}

/**
 * SetRealname
 *
 * Sets the user's realname.
 *
 * @param Realname the new realname
 */
00284 bool CNick::SetRealname(const char *Realname) {
      IMPL_NICKSET(m_Realname, Realname, true);
}

/**
 * SetServer
 *
 * Sets the server for a user.
 *
 * @param Server the server which the user is using
 */
00295 bool CNick::SetServer(const char *Server) {
      IMPL_NICKSET(m_Server, Server, true);
}

/**
 * InternalGetSite
 *
 * Returns the user's site without querying other nick
 * objects if the information is not available.
 */
00305 const char *CNick::InternalGetSite(void) const {
      if (m_Site == NULL) {
            return NULL;
      }

      char *Host = strstr(m_Site, "!");

      if (Host) {
            return Host + 1;
      } else {
            return m_Site;
      }
}

/**
 * InternalGetRealname
 *
 * Returns the user's realname without querying other nick
 * objects if the information is not available.
 */
00325 const char *CNick::InternalGetRealname(void) const {
      return m_Realname;
}

/**
 * InternalGetServer
 *
 * Returns the user's server without querying other nick
 * objects if the information is not available.
 */
00335 const char *CNick::InternalGetServer(void) const {
      return m_Server;
}

/**
 * IMPL_NICKACCESSOR
 *
 * Implements a Get*() function
 *
 * @param Name the name of the attribute
 */
#define IMPL_NICKACCESSOR(Name) \
      const char *Value; \
      int a = 0; \
\
      if ((Value = Name()) != NULL) { \
            return Value; \
      } \
\
      while (hash_t<CChannel *> *Chan = GetOwner()->GetOwner()->GetChannels()->Iterate(a++)) { \
            if (!Chan->Value->HasNames()) \
                  continue; \
\
            CNick *NickObj = Chan->Value->GetNames()->Get(m_Nick); \
\
            if (NickObj && strcasecmp(NickObj->GetNick(), m_Nick) == 0 && NickObj->Name() != NULL) \
                  return NickObj->Name(); \
      } \
\
      return NULL;

/**
 * GetSite
 *
 * Returns the user's site.
 */
00371 const char *CNick::GetSite(void) const {
      IMPL_NICKACCESSOR(InternalGetSite)
}

/**
 * GetRealname
 *
 * Returns the user's realname.
 */
00380 const char *CNick::GetRealname(void) const {
      IMPL_NICKACCESSOR(InternalGetRealname)
}

/**
 * GetServer
 *
 * Returns the user's server.
 */
00389 const char *CNick::GetServer(void) const {
      IMPL_NICKACCESSOR(InternalGetServer)
}

/**
 * GetChanJoin
 *
 * Returns a timestamp which determines when
 * the user joined the channel.
 */
00399 time_t CNick::GetChanJoin(void) const {
      return m_Creation;
}

/**
 * GetIdleSince
 *
 * Returns a timestamp which determines when
 * the user last said something.
 */
00409 time_t CNick::GetIdleSince(void) const {
      return m_IdleSince;
}

/**
 * SetIdleSince
 *
 * Sets the timestamp of the user's last channel PRIVMSG.
 *
 * @param Time the new timestamp
 */
00420 bool CNick::SetIdleSince(time_t Time) {
      m_IdleSince = Time;

      return true;
}

/**
 * GetTag
 *
 * Returns the value of a user-specific tag.
 *
 * @param Name the name of the tag
 */
00433 const char *CNick::GetTag(const char *Name) const {
      for (unsigned int i = 0; i < m_Tags.GetLength(); i++) {
            if (strcasecmp(m_Tags[i].Name, Name) == 0) {
                  return m_Tags[i].Value;
            }
      }

      return NULL;
}

/**
 * SetTag
 *
 * Sets a user-specific tag.
 *
 * @param Name the name of the tag
 * @param Value the value of the tag
 */
00451 bool CNick::SetTag(const char *Name, const char *Value) {
      nicktag_t NewTag;

      if (Name == NULL) {
            return false;
      }

      for (unsigned int i = 0; i < m_Tags.GetLength(); i++) {
            if (strcasecmp(m_Tags[i].Name, Name) == 0) {
                  ufree(m_Tags[i].Name);
                  ufree(m_Tags[i].Value);

                  m_Tags.Remove(i);

                  break;
            }
      }

      if (Value == NULL) {
            return true;
      }

      NewTag.Name = ustrdup(Name);

      CHECK_ALLOC_RESULT(NewTag.Name, ustrdup) {
            return false;
      } CHECK_ALLOC_RESULT_END;

      NewTag.Value = ustrdup(Value);

      CHECK_ALLOC_RESULT(NewTag.Value, ustrdup) {
            ufree(NewTag.Name);

            return false;
      } CHECK_ALLOC_RESULT_END;

      return m_Tags.Insert(NewTag);
}

Generated by  Doxygen 1.6.0   Back to index