Example #1
0
/* Returns memberfields if the nick is in the member list.
 */
memberlist *ismember(struct chanset_t *chan, const char *nick)
{
  register memberlist	*x = NULL;

  if (chan && nick && nick[0])
    for (x = chan->channel.member; x && x->nick[0]; x = x->next)
      if (!rfc_casecmp(x->nick, nick))
        return x;
  return NULL;
}
Example #2
0
/* Check for expired timed-invites.
 */
static void check_expired_invites(void)
{
  maskrec *u, *u2;
  struct chanset_t *chan;
  masklist *b;

  if (!use_invites)
    return;
  for (u = global_invites; u; u = u2) {
    u2 = u->next;
    if (!(u->flags & MASKREC_PERM) && (now >= u->expire)) {
      putlog(LOG_MISC, "*", "%s %s (%s)", INVITES_NOLONGER,
             u->mask, MISC_EXPIRED);
      for (chan = chanset; chan; chan = chan->next)
        if (!(chan->channel.mode & CHANINV))
          for (b = chan->channel.invite; b->mask[0]; b = b->next)
            if (!rfc_casecmp(b->mask, u->mask) &&
                expired_mask(chan, b->who) && b->timer != now) {
              add_mode(chan, '-', 'I', u->mask);
              b->timer = now;
            }
      u_delinvite(NULL, u->mask, 1);
    }
  }
  /* Check for specific channel-domain invites expiring */
  for (chan = chanset; chan; chan = chan->next) {
    for (u = chan->invites; u; u = u2) {
      u2 = u->next;
      if (!(u->flags & MASKREC_PERM) && (now >= u->expire)) {
        putlog(LOG_MISC, "*", "%s %s %s %s (%s)", INVITES_NOLONGER,
               u->mask, MISC_ONLOCALE, chan->dname, MISC_EXPIRED);
        if (!(chan->channel.mode & CHANINV))
          for (b = chan->channel.invite; b->mask[0]; b = b->next)
            if (!rfc_casecmp(b->mask, u->mask) &&
                expired_mask(chan, b->who) && b->timer != now) {
              add_mode(chan, '-', 'I', u->mask);
              b->timer = now;
            }
        u_delinvite(chan, u->mask, 1);
      }
    }
  }
}
Example #3
0
static int u_delinvite(struct chanset_t *c, char *who, int doit)
{
  int j, i = 0;
  maskrec *t;
  maskrec **u = c ? &(c->invites) : &global_invites;
  char temp[256];

  if (!strchr(who, '!') && str_isdigit(who)) {
    j = atoi(who);
    j--;
    for (; (*u) && j; u = &((*u)->next), j--);
    if (*u) {
      strncpyz(temp, (*u)->mask, sizeof temp);
      i = 1;
    } else
      return -j - 1;
  } else {
    /* Find matching host, if there is one */
    for (; *u && !i; u = &((*u)->next))
      if (!rfc_casecmp((*u)->mask, who)) {
        strncpyz(temp, who, sizeof temp);
        i = 1;
        break;
      }
    if (!*u)
      return 0;
  }
  if (i && doit) {
    if (!noshare) {
      char *mask = str_escape(temp, ':', '\\');

      if (mask) {
        /* Distribute chan invites differently */
        if (c)
          shareout(c, "-invc %s %s\n", c->dname, mask);
        else
          shareout(NULL, "-inv %s\n", mask);
        nfree(mask);
      }
    }
    if (lastdeletedmask)
      nfree(lastdeletedmask);
    lastdeletedmask = nmalloc(strlen((*u)->mask) + 1);
    strcpy(lastdeletedmask, (*u)->mask);
    nfree((*u)->mask);
    if ((*u)->desc)
      nfree((*u)->desc);
    if ((*u)->user)
      nfree((*u)->user);
    t = *u;
    *u = (*u)->next;
    nfree(t);
  }
  return i;
}
Example #4
0
/* Got nick change.
 */
static int gotnick(char *from, char *msg)
{
  char *nick, *alt = get_altbotnick();

  nick = splitnick(&from);
  fixcolon(msg);
  check_queues(nick, msg);
  if (match_my_nick(nick)) {
    /* Regained nick! */
    strncpyz(botname, msg, NICKLEN);
    altnick_char = 0;
    if (!strcmp(msg, origbotname)) {
      putlog(LOG_SERV | LOG_MISC, "*", "Regained nickname '%s'.", msg);
      nick_juped = 0;
    } else if (alt[0] && !strcmp(msg, alt))
      putlog(LOG_SERV | LOG_MISC, "*", "Regained alternate nickname '%s'.",
             msg);
    else if (keepnick && strcmp(nick, msg)) {
      putlog(LOG_SERV | LOG_MISC, "*", "Nickname changed to '%s'???", msg);
      if (!rfc_casecmp(nick, origbotname)) {
        putlog(LOG_MISC, "*", IRC_GETORIGNICK, origbotname);
        dprintf(DP_SERVER, "NICK %s\n", origbotname);
      } else if (alt[0] && !rfc_casecmp(nick, alt) &&
               egg_strcasecmp(botname, origbotname)) {
        putlog(LOG_MISC, "*", IRC_GETALTNICK, alt);
        dprintf(DP_SERVER, "NICK %s\n", alt);
      }
    } else
      putlog(LOG_SERV | LOG_MISC, "*", "Nickname changed to '%s'???", msg);
  } else if ((keepnick) && (rfc_casecmp(nick, msg))) {
    /* Only do the below if there was actual nick change, case doesn't count */
    if (!rfc_casecmp(nick, origbotname)) {
      putlog(LOG_MISC, "*", IRC_GETORIGNICK, origbotname);
      dprintf(DP_SERVER, "NICK %s\n", origbotname);
    } else if (alt[0] && !rfc_casecmp(nick, alt) &&
             egg_strcasecmp(botname, origbotname)) {
      putlog(LOG_MISC, "*", IRC_GETALTNICK, altnick);
      dprintf(DP_SERVER, "NICK %s\n", altnick);
    }
  }
  return 0;
}
Example #5
0
/* Merge of u_equals_ban(), u_equals_exempt() and u_equals_invite().
 *
 * Returns:
 *   0       not a ban
 *   1       temporary ban
 *   2       perm ban
 */
static int u_equals_mask(maskrec *u, char *mask)
{
  for (; u; u = u->next)
    if (!rfc_casecmp(u->mask, mask)) {
      if (u->flags & MASKREC_PERM)
        return 2;
      else
        return 1;
    }
  return 0;
}
Example #6
0
static char *
log_create_pathname (char *servname, char *channame, char *netname)
{
	char fname[384];
	char fnametime[384];
	time_t now;

	if (!netname)
	{
		netname = g_strdup ("NETWORK");
	}
	else
	{
		netname = log_create_filename (netname);
	}

	/* first, everything is in UTF-8 */
	if (!rfc_casecmp (channame, servname))
	{
		channame = g_strdup ("server");
	}
	else
	{
		channame = log_create_filename (channame);
	}

	servname = log_create_filename (servname);

	log_insert_vars (fname, sizeof (fname), prefs.hex_irc_logmask, channame, netname, servname);
	g_free (channame);
	g_free (netname);
	g_free (servname);

	/* insert time/date */
	now = time (NULL);
	strftime_utf8 (fnametime, sizeof (fnametime), fname, now);

	/* If one uses log mask variables, such as "%c/...", %c will be empty upon
	 * connecting since there's no channel name yet, so we have to make sure
	 * we won't try to write to the FS root. */
	if (g_path_is_absolute (prefs.hex_irc_logmask))
	{
		g_snprintf (fname, sizeof (fname), "%s", fnametime);
	}
	else	/* relative path */
	{
		g_snprintf (fname, sizeof (fname), "%s" G_DIR_SEPARATOR_S "logs" G_DIR_SEPARATOR_S "%s", get_xdir (), fnametime);
	}

	/* create all the subdirectories */
	mkdir_p (fname);

	return g_strdup (fname);
}
Example #7
0
File: text.c Project: sb057/hexchat
static char *
log_create_pathname (char *servname, char *channame, char *netname)
{
	char fname[384];
	char fnametime[384];
	char *fs;
	struct tm *tm;
	time_t now;

	if (!netname)
	{
		netname = "NETWORK";
	}

	/* first, everything is in UTF-8 */
	if (!rfc_casecmp (channame, servname))
	{
		channame = strdup ("server");
	}
	else
	{
		channame = log_create_filename (channame);
	}

	log_insert_vars (fname, sizeof (fname), prefs.logmask, channame, netname, servname);
	free (channame);

	/* insert time/date */
	now = time (NULL);
	tm = localtime (&now);
	strftime (fnametime, sizeof (fnametime), fname, tm);

	/* create final path/filename */
	if (logmask_is_fullpath ())
	{
		snprintf (fname, sizeof (fname), "%s", fnametime);
	}
	else	/* relative path */
	{
		snprintf (fname, sizeof (fname), "%s/logs/%s", get_xdir_utf8 (), fnametime);
	}

	/* now we need it in FileSystem encoding */
	fs = xchat_filename_from_utf8 (fname, -1, 0, 0, 0);

	/* create all the subdirectories */
	if (fs)
	{
		mkdir_p (fs);
	}

	return fs;
}
Example #8
0
/* Clear the user pointer of a specific nick in the chanlists.
 *
 * Necessary when a hostmask is added/removed, a nick changes, etc.
 * Does not completely invalidate the channel cache like clear_chanlist().
 */
void clear_chanlist_member(const char *nick)
{
  register memberlist *m;
  register struct chanset_t *chan;

  for (chan = chanset; chan; chan = chan->next)
    for (m = chan->channel.member; m && m->nick[0]; m = m->next)
      if (!rfc_casecmp(m->nick, nick)) {
        m->user = NULL;
        m->tried_getuser = 0;
        break;
      }
}
Example #9
0
static char *
log_create_pathname (char *servname, char *channame, char *netname)
{
	char fname[384];
	char fnametime[384];
	struct tm *tm;
	time_t now;

	if (!netname)
	{
		netname = strdup ("NETWORK");
	}
	else
	{
		netname = log_create_filename (netname);
	}

	/* first, everything is in UTF-8 */
	if (!rfc_casecmp (channame, servname))
	{
		channame = strdup ("server");
	}
	else
	{
		channame = log_create_filename (channame);
	}

	log_insert_vars (fname, sizeof (fname), prefs.hex_irc_logmask, channame, netname, servname);
	free (channame);
	free (netname);

	/* insert time/date */
	now = time (NULL);
	tm = localtime (&now);
	strftime_validated (fnametime, sizeof (fnametime), fname, tm);

	/* create final path/filename */
	if (logmask_is_fullpath ())
	{
		snprintf (fname, sizeof (fname), "%s", fnametime);
	}
	else	/* relative path */
	{
		snprintf (fname, sizeof (fname), "%s" G_DIR_SEPARATOR_S "logs" G_DIR_SEPARATOR_S "%s", get_xdir (), fnametime);
	}

	/* create all the subdirectories */
	mkdir_p (fname);

	return g_strdup(fname);
}
Example #10
0
static int
notify_netcmp (char *str, void *serv)
{
	char *net = despacify_dup (server_get_network (serv, TRUE));

	if (rfc_casecmp (str, net) == 0)
	{
		free (net);
		return 0;	/* finish & return FALSE from token_foreach() */
	}

	free (net);
	return 1;	/* keep going... */
}
Example #11
0
/* If this user@host is in a channel, set it (it was null)
 */
void set_chanlist(const char *host, struct userrec *rec)
{
  char *nick, *uhost, buf[UHOSTLEN];
  register memberlist *m;
  register struct chanset_t *chan;

  strncpyz(buf, host, sizeof buf);
  uhost = buf;
  nick = splitnick(&uhost);
  for (chan = chanset; chan; chan = chan->next)
    for (m = chan->channel.member; m && m->nick[0]; m = m->next)
      if (!rfc_casecmp(nick, m->nick) && !egg_strcasecmp(uhost, m->userhost))
        m->user = rec;
}
Example #12
0
void set_user_flagrec(struct userrec *u, struct flag_record *fr,
		      char *chname)
{
  struct chanuserrec *cr = NULL;
  int oldflags = fr->match;
  char buffer[100];
  struct chanset_t *ch;

  if (!u)
    return;
  if (oldflags & FR_GLOBAL) {
    u->flags = fr->global;

    u->flags_udef = fr->udef_global;
    if (!noshare && !(u->flags & USER_UNSHARED)) {
      fr->match = FR_GLOBAL;
      build_flags(buffer, fr, NULL);
      shareout(NULL, "a %s %s\n", u->handle, buffer);
    }
  }
  if ((oldflags & FR_BOT) && (u->flags & USER_BOT))
    set_user(&USERENTRY_BOTFL, u, (void *) fr->bot);
  /* dont share bot attrs */
  if ((oldflags & FR_CHAN) && chname) {
    for (cr = u->chanrec; cr; cr = cr->next)
      if (!rfc_casecmp(chname, cr->channel))
	break;
    ch = findchan(chname);
    if (!cr && ch) {
      cr = user_malloc(sizeof(struct chanuserrec));
      bzero(cr, sizeof(struct chanuserrec));

      cr->next = u->chanrec;
      u->chanrec = cr;
      strncpy(cr->channel, chname, 80);
      cr->channel[80] = 0;
    }
    if (cr && ch) {
      cr->flags = fr->chan;
      cr->flags_udef = fr->udef_chan;
      if (!noshare && !(u->flags & USER_UNSHARED) && channel_shared(ch)) {
	fr->match = FR_CHAN;
	build_flags(buffer, fr, NULL);
	shareout(ch, "a %s %s %s\n", u->handle, buffer, chname);
      }
    }
  }
  fr->match = oldflags;
}
Example #13
0
/* Shortcut for get_user_by_host -- might have user record in one
 * of the channel caches.
 */
struct userrec *check_chanlist(const char *host)
{
  char				*nick = NULL, *uhost = NULL, buf[UHOSTLEN] = "";
  register memberlist		*m = NULL;
  register struct chanset_t	*chan = NULL;

  strlcpy(buf, host, sizeof buf);
  uhost = buf;
  nick = splitnick(&uhost);
  for (chan = chanset; chan; chan = chan->next)
    for (m = chan->channel.member; m && m->nick[0]; m = m->next) 
      if (!rfc_casecmp(nick, m->nick) && !strcasecmp(uhost, m->userhost))
	return m->user;
  return NULL;
}
Example #14
0
static int gotkick(char *from, char *msg)
{
  char *nick;

  nick = from;
  if (rfc_casecmp(nick, botname))
    /* Not my kick, I don't need to bother about it. */
    return 0;
  if (use_penalties) {
    last_time += 2;
    if (raw_log)
      putlog(LOG_SRVOUT, "*", "adding 2secs penalty (successful kick)");
  }
  return 0;
}
Example #15
0
static void mns_chan(int idx, char *par, char *bot)
{
  char *chname = NULL, buf2[1024] = "";
  struct chanset_t *chan = NULL;
  int i;

  if (!bot)
    putlog(LOG_CMDS, "*", "#%s# -chan %s", dcc[idx].nick, par);

  if (!par[0]) {
    dprintf(idx, "Usage: -chan [%s]<channel>\n", CHANMETA);
    return;
  }
  chname = newsplit(&par);

  simple_snprintf(buf2, sizeof(buf2), "cpart %s %s", chname, bot ? bot : "*");
  if (bot)		/* bot will just set it +inactive */
    putbot(bot, buf2);
  else
    putallbots(buf2);

  chan = findchan_by_dname(chname);
  if (!chan) {
    if ((chan = findchan(chname)))
      dprintf(idx, "That channel exists with a short name of %s, use that.\n", chan->dname);
    else
      dprintf(idx, "That channel doesn't exist!\n");
    return;
  }

  if (!bot) {
    for (i = 0; i < dcc_total; i++) {
      if (dcc[i].type && (dcc[i].type->flags & DCT_CHAT) && 
          !rfc_casecmp(dcc[i].u.chat->con_chan, chan->dname)) {
        dprintf(i, "%s is no longer a valid channel, changing your console to '*'\n", chname);
        strlcpy(dcc[i].u.chat->con_chan, "*", 2);
        console_dostore(i, 0);
      }
    }
    remove_channel(chan);
    if (conf.bot->hub)
      write_userfile(idx);
    dprintf(idx, "Channel %s removed from the botnet.\n", chname);
    dprintf(idx, "This includes any channel specific bans, invites, exemptions and user records that you set.\n");
  } else
    dprintf(idx, "Channel %s removed from the bot: %s\n", chname, bot);
}
Example #16
0
void get_user_flagrec(struct userrec *u, struct flag_record *fr,
		      char *chname)
{
  struct chanuserrec *cr = NULL;

  if (!u) {
    fr->global = fr->udef_global = fr->chan = fr->udef_chan = fr->bot = 0;

    return;
  }
  if (fr->match & FR_GLOBAL) {
    fr->global = u->flags;

    fr->udef_global = u->flags_udef;
  } else {
    fr->global = 0;

    fr->udef_global = 0;
  }
  if (fr->match & FR_BOT) {
    fr->bot = (long) get_user(&USERENTRY_BOTFL, u);
  } else
    fr->bot = 0;
  if (fr->match & FR_CHAN) {
    if (fr->match & FR_ANYWH) {
      fr->chan = u->flags;
      fr->udef_chan = u->flags_udef;
      for (cr = u->chanrec; cr; cr = cr->next)
	if (findchan(cr->channel)) {
	  fr->chan |= cr->flags;
	  fr->udef_chan |= cr->flags_udef;
	}
    } else {
      if (chname)
	for (cr = u->chanrec; cr; cr = cr->next)
	  if (!rfc_casecmp(chname, cr->channel))
	    break;
      if (chname && cr) {
	fr->chan = cr->flags;
	fr->udef_chan = cr->flags_udef;
      } else {
	fr->chan = 0;
	fr->udef_chan = 0;
      }
    }
  }
}
Example #17
0
static void got_unexempt(struct chanset_t *chan, char *nick, char *from,
                         char *who, char *ch, struct userrec *u)
{
  masklist *e = chan->channel.exempt, *old = NULL;
  masklist *b;
  int match = 0;

  while (e && e->mask[0] && rfc_casecmp(e->mask, who)) {
    old = e;
    e = e->next;
  }
  if (e && e->mask[0]) {
    if (old)
      old->next = e->next;
    else
      chan->channel.exempt = e->next;
    nfree(e->mask);
    nfree(e->who);
    nfree(e);
  }
  check_tcl_mode(nick, from, u, chan->dname, "-e", who);
  if (!(chan = modebind_refresh(ch, from, &user, NULL, NULL)))
    return;

  if (channel_pending(chan))
    return;

  if (u_sticky_mask(chan->exempts, who) || u_sticky_mask(global_exempts, who))
    add_mode(chan, '+', 'e', who);

  /* If exempt was removed by master then leave it else check for bans */
  if (!nick[0] && glob_bot(user) && !glob_master(user) && !chan_master(user)) {
    b = chan->channel.ban;
    while (b->mask[0] && !match) {
      if (mask_match(b->mask, who)) {
        add_mode(chan, '+', 'e', who);
        match = 1;
      } else
        b = b->next;
    }
  }
  if ((u_equals_mask(global_exempts, who) ||
      u_equals_mask(chan->exempts, who)) && me_op(chan) &&
      !channel_dynamicexempts(chan) && (!glob_bot(user) ||
      !(bot_flags(u) & BOT_SHARE)))
    add_mode(chan, '+', 'e', who);
}
Example #18
0
/* Adds a ban, exempt or invite mask to the list
 * m should be chan->channel.(exempt|invite|ban)
 */
static void newmask(masklist *m, char *s, char *who)
{
    for (; m && m->mask[0] && rfc_casecmp(m->mask, s); m = m->next);
    if (m->mask[0])
        return;                     /* Already existent mask */

    m->next = (masklist *) channel_malloc(sizeof(masklist));
    m->next->next = NULL;
    m->next->mask = (char *) channel_malloc(1);
    m->next->mask[0] = 0;
    nfree(m->mask);
    m->mask = (char *) channel_malloc(strlen(s) + 1);
    strcpy(m->mask, s);
    m->who = (char *) channel_malloc(strlen(who) + 1);
    strcpy(m->who, who);
    m->timer = now;
}
Example #19
0
/* We try to change to a preferred unique nick here. We always first try the
 * specified alternate nick. If that failes, we repeatedly modify the nick
 * until it gets accepted.
 *
 * sent nick:
 *     "<altnick><c>"
 *                ^--- additional count character: 1-9^-_\\[]`a-z
 *          ^--------- given, alternate nick
 *
 * The last added character is always saved in altnick_char. At the very first
 * attempt (were altnick_char is 0), we try the alternate nick without any
 * additions.
 *
 * fixed by guppy (1999/02/24) and Fabian (1999/11/26)
 */
static int gotfake433(char *from)
{
  int l = strlen(botname) - 1;

  /* First run? */
  if (altnick_char == 0) {
    char *alt = get_altbotnick();

    if (alt[0] && (rfc_casecmp(alt, botname)))
      /* Alternate nickname defined. Let's try that first. */
      strcpy(botname, alt);
    else {
      /* Fall back to appending count char. */
      altnick_char = '0';
      if ((l + 1) == nick_len) {
        botname[l] = altnick_char;
      } else {
        botname[++l] = altnick_char;
        botname[l + 1] = 0;
      }
    }
    /* No, we already tried the default stuff. Now we'll go through variations
     * of the original alternate nick.
     */
  } else {
    char *oknicks = "^-_\\[]`";
    char *p = strchr(oknicks, altnick_char);

    if (p == NULL) {
      if (altnick_char == '9')
        altnick_char = oknicks[0];
      else
        altnick_char = altnick_char + 1;
    } else {
      p++;
      if (!*p)
        altnick_char = 'a' + randint(26);
      else
        altnick_char = (*p);
    }
    botname[l] = altnick_char;
  }
  putlog(LOG_MISC, "*", IRC_BOTNICKINUSE, botname);
  dprintf(DP_MODE, "NICK %s\n", botname);
  return 0;
}
Example #20
0
/* ignore_exists ():
 * returns: struct ig, if this mask is in the ignore list already
 *          NULL, otherwise
 */
struct ignore *
ignore_exists (char *mask)
{
	struct ignore *ig = NULL;
	GSList *list;

	list = ignore_list;
	while (list)
	{
		ig = (struct ignore *) list->data;
		if (!rfc_casecmp (ig->mask, mask))
			return ig;
		list = list->next;
	}
	return NULL;

}
Example #21
0
/* handonanychan():
 * checks if the given user is on any channel (no matter under which nick)
 */
static struct chanset_t *handonanychan(char *hand)
{
  struct chanset_t *ch;
  memberlist *m;

  for (ch = chanset; ch; ch = ch->next) {
    if (ch->channel.members > 0) {
      for (m = ch->channel.member; m; m = m->next) {
        if (m->user) {
          if (m->user->handle && !rfc_casecmp(m->user->handle, hand))
            return ch;
        }
      }
    }
  }
  return NULL;
}
Example #22
0
void
set_user_flagrec(struct userrec *u, struct flag_record *fr, const char *chname)
{
  if (!u)
    return;

  struct chanuserrec *cr = NULL;
  flag_t oldflags = fr->match;
  char buffer[100] = "";
  struct chanset_t *ch;


  if (oldflags & FR_GLOBAL) {
    u->flags = fr->global;

    if (!noshare) {
      fr->match = FR_GLOBAL;
      build_flags(buffer, fr, NULL);
      shareout("a %s %s\n", u->handle, buffer);
    }
  }

  if ((oldflags & FR_CHAN) && chname) {
    for (cr = u->chanrec; cr; cr = cr->next)
      if (!rfc_casecmp(chname, cr->channel))
        break;
    ch = findchan_by_dname(chname);
    if (!cr && ch) {
      cr = (struct chanuserrec *) my_calloc(1, sizeof(struct chanuserrec));

      cr->next = u->chanrec;
      u->chanrec = cr;
      strlcpy(cr->channel, chname, sizeof cr->channel);
    }
    if (cr && ch) {
      cr->flags = fr->chan;
      if (!noshare) {
        fr->match = FR_CHAN;
        build_flags(buffer, fr, NULL);
        shareout("a %s %s %s\n", u->handle, buffer, chname);
      }
    }
  }
  fr->match = oldflags;
}
Example #23
0
/* handonchan():
 * checks if the given user is on the channel and returns its nick
 */
static char *handonchan(char *hand, char *chan)
{
  struct chanset_t *ch;
  memberlist *m;

  ch = findchan_by_dname(chan);
  if (!ch)
    return 0;
  if (ch->channel.members > 0) {
    for (m = ch->channel.member; m; m = m->next) {
      if (m->user) {
        if (m->user->handle && !rfc_casecmp(m->user->handle, hand))
          return m->nick;
      }
    }
  }
  return NULL;
}
Example #24
0
static int msg_ident(char *nick, char *host, struct userrec *u, char *par)
{
  char s[UHOSTLEN] = "", s1[UHOSTLEN] = "", *pass = NULL, who[HANDLEN + 1] = "";
  struct userrec *u2 = NULL;

  if (match_my_nick(nick) || (u && u->bot))
    return BIND_RET_BREAK;

  pass = newsplit(&par);
  if (!par[0])
    strlcpy(who, nick, sizeof(who));
  else {
    strlcpy(who, par, sizeof(who));
  }
  bd::String msg;
  u2 = get_user_by_handle(userlist, who);
  if (u2 && rfc_casecmp(who, origbotname) && !u2->bot) {
    /* This could be used as detection... */
    if (u_pass_match(u2, "-")) {
      putlog(LOG_CMDS, "*", "(%s!%s) !*! IDENT %s", nick, host, who);
    } else if (!u_pass_match(u2, pass)) {
      putlog(LOG_CMDS, "*", "(%s!%s) !*! failed IDENT %s", nick, host, who);
      return BIND_RET_BREAK;
    } else if (u == u2) {
      notice(nick, "I recognize you there.", DP_HELP);
      return BIND_RET_BREAK;
    } else if (u) {
      msg = bd::String::printf("You're not %s, you're %s.", who, u->handle);
      notice(nick, msg.c_str(), DP_HELP);
      return BIND_RET_BREAK;
    } else {
      putlog(LOG_CMDS, "*", "(%s!%s) !*! IDENT %s", nick, host, who);
      simple_snprintf(s, sizeof s, "%s!%s", nick, host);
      maskaddr(s, s1, 0); /* *!user@host */
      msg = bd::String::printf("Added hostmask: %s", s1);
      notice(nick, msg.c_str(), DP_HELP);
      addhost_by_handle(who, s1);
      check_this_user(who, 0, NULL);
      return BIND_RET_BREAK;
    }
  }
  putlog(LOG_CMDS, "*", "(%s!%s) !*! failed IDENT %s", nick, host, who);
  return BIND_RET_BREAK;
}
Example #25
0
/* Expire mask originally set by `who' on `chan'?
 *
 * We might not want to expire masks in all cases, as other bots
 * often tend to immediately reset masks they've listed in their
 * internal ban list, making it quite senseless for us to remove
 * them in the first place.
 *
 * Returns 1 if a mask on `chan' by `who' may be expired and 0 if
 * not.
 */
static int expired_mask(struct chanset_t *chan, char *who)
{
  memberlist *m, *m2;
  char buf[UHOSTLEN], *snick, *sfrom;
  struct userrec *u;

  /* Always expire masks, regardless of who set it? */
  if (force_expire)
    return 1;

  strcpy(buf, who);
  sfrom = buf;
  snick = splitnick(&sfrom);

  if (!snick[0])
    return 1;

  m = ismember(chan, snick);
  if (!m)
    for (m2 = chan->channel.member; m2 && m2->nick[0]; m2 = m2->next)
      if (!egg_strcasecmp(sfrom, m2->userhost)) {
        m = m2;
        break;
      }

  if (!m || !chan_hasop(m) || !rfc_casecmp(m->nick, botname))
    return 1;

  /* At this point we know the person/bot who set the mask is currently
   * present in the channel and has op.
   */

  if (m->user)
    u = m->user;
  else {
    simple_sprintf(buf, "%s!%s", m->nick, m->userhost);
    u = get_user_by_host(buf);
  }
  /* Do not expire masks set by bots. */
  if (u && u->flags & USER_BOT)
    return 0;
  else
    return 1;
}
Example #26
0
static char* log_create_pathname(char *servname, char *channame, char *netname)
{
	char fname[384];
	char fnametime[384];
	char *fs;
	tm *tm;
	time_t now;

	if (!netname)
		netname = "NETWORK";

	// first, everything is in UTF-8
	if (!rfc_casecmp(channame, servname))
		channame = strdup("server");
	else
		channame = log_create_filename(channame);
	log_insert_vars(fname, sizeof(fname), prefs.logmask, channame, netname, servname);
	free(channame);

	// insert time/date
	now = time(nullptr);
	tm = localtime(&now);
	strftime(fnametime, sizeof(fnametime), fname, tm);

	// create final path/filename
#ifdef WIN32
	if (fnametime[0] == '/' || (fnametime[0] >= 'A' && fnametime[1] == ':'))
#else
	if (fnametime[0] == '/')	// is it fullpath already?
#endif
		snprintf(fname, sizeof(fname), "%s", fnametime);
	else
		snprintf(fname, sizeof(fname), "%s/xchatlogs/%s", get_xdir_utf8(), fnametime);

	// now we need it in FileSystem encoding
	fs = xchat_filename_from_utf8(fname, -1, 0, 0, 0);

	// create all the subdirectories
	if (fs)
		mkdir_p(fs);

	return fs;
}
Example #27
0
/* Always pass the dname (display name) to this function for chname <cybah>
 */
void
get_user_flagrec(struct userrec *u, struct flag_record *fr, const char *chname, const struct chanset_t* chan)
{
  fr->bot = 0;
  if (!u) {
    fr->global = fr->chan = 0;

    return;
  }

  if (u->bot)
    fr->bot = 1;

  fr->global = (fr->match & FR_GLOBAL) ? u->flags : 0;

  if (fr->match & FR_CHAN) {
    struct chanuserrec *cr = NULL;

    if ((fr->match & FR_ANYWH) || (fr->match & FR_ANYCH)) {
      if (fr->match & FR_ANYWH)
        fr->chan = u->flags;
      for (cr = u->chanrec; cr; cr = cr->next) {
        if (chan || findchan_by_dname(cr->channel)) {
          fr->chan |= cr->flags;
        }
      }
    } else {
      if (chname) {
        for (cr = u->chanrec; cr; cr = cr->next) {
          if (!rfc_casecmp(chname, cr->channel))
            break;
        }
      }

      if (cr) {
        fr->chan = cr->flags;
      } else {
        fr->chan = 0;
      }
    }
  }
}
Example #28
0
static void del_chanrec(struct userrec *u, char *chname)
{
  struct chanuserrec *ch = u->chanrec, *lst = NULL;

  while (ch) {
    if (!rfc_casecmp(chname, ch->channel)) {
      if (lst == NULL)
        u->chanrec = ch->next;
      else
        lst->next = ch->next;
      if (ch->info != NULL)
        nfree(ch->info);
      nfree(ch);
      if (!noshare && !(u->flags & USER_UNSHARED))
        shareout(findchan_by_dname(chname), "-cr %s %s\n", u->handle, chname);
      return;
    }
    lst = ch;
    ch = ch->next;
  }
}
Example #29
0
/* Set sticky attribute for a mask.
 */
static int u_setsticky_mask(struct chanset_t *chan, maskrec *u, char *uhost,
                            int sticky, char *botcmd)
{
  int j;

  if (str_isdigit(uhost))
    j = atoi(uhost);
  else
    j = -1;

  while (u) {
    if (j >= 0)
      j--;

    if (!j || ((j < 0) && !rfc_casecmp(u->mask, uhost))) {
      if (sticky > 0)
        u->flags |= MASKREC_STICKY;
      else if (!sticky)
        u->flags &= ~MASKREC_STICKY;
      else /* We don't actually want to change, just skip over */
        return 0;
      if (!j)
        strcpy(uhost, u->mask);

      if (!noshare)
        shareout(chan, "%s %s %d %s\n", botcmd, uhost, sticky,
                 (chan) ? chan->dname : "");
      return 1;
    }

    u = u->next;
  }

  if (j >= 0)
    return -j;

  return 0;
}
Example #30
0
/* Removes a nick from the channel member list (returns 1 if successful)
 */
static int killmember(struct chanset_t *chan, char *nick)
{
    memberlist *x, *old;

    old = NULL;
    for (x = chan->channel.member; x && x->nick[0]; old = x, x = x->next)
        if (!rfc_casecmp(x->nick, nick))
            break;
    if (!x || !x->nick[0]) {
        if (!channel_pending(chan) && !channel_djoins(chan))
            putlog(LOG_MISC, "*", "(!) killmember(%s) -> nonexistent", nick);
        return 0;
    }
    if (old)
        old->next = x->next;
    else
        chan->channel.member = x->next;
    nfree(x);
    chan->channel.members--;

    /* The following two errors should NEVER happen. We will try to correct
     * them though, to keep the bot from crashing.
     */
    if (chan->channel.members < 0) {
        chan->channel.members = 0;
        for (x = chan->channel.member; x && x->nick[0]; x = x->next)
            chan->channel.members++;
        putlog(LOG_MISC, "*", "(!) actually I know of %d members.",
               chan->channel.members);
    }
    if (!chan->channel.member) {
        chan->channel.member = (memberlist *) channel_malloc(sizeof(memberlist));
        chan->channel.member->nick[0] = 0;
        chan->channel.member->next = NULL;
    }
    return 1;
}