コード例 #1
0
ファイル: m_who.c プロジェクト: Cloudxtreme/bahamut
int m_who(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
    aClient *ac;
    chanMember *cm;
    Link *lp;
    int shown=0, i=0, showall=IsAnOper(sptr);
    char status[4];

    /* drop nonlocal clients */
    if(!MyClient(sptr))
	return 0;
    
    if(!build_searchopts(sptr, parc-1, parv+1))
	return 0; /* /who was no good */
    
    if(wsopts.gcos!=NULL && (strchr(wsopts.gcos, '?'))==NULL &&
       (strchr(wsopts.gcos, '*'))==NULL)
	gchkfn=mycmp;
    else
	gchkfn=match;
    if(wsopts.nick!=NULL && (strchr(wsopts.nick, '?'))==NULL &&
       (strchr(wsopts.nick, '*'))==NULL)
	nchkfn=mycmp;
    else
	nchkfn=match;
    if(wsopts.user!=NULL && (strchr(wsopts.user, '?'))==NULL &&
       (strchr(wsopts.user, '*'))==NULL)
	uchkfn=mycmp;
    else
	uchkfn=match;
    if(wsopts.host!=NULL && (strchr(wsopts.host, '?'))==NULL &&
       (strchr(wsopts.host, '*'))==NULL)
	hchkfn=mycmp;
    else
	hchkfn=match;

    if(wsopts.ip!=NULL && (strchr(wsopts.ip, '?'))==NULL &&
       (strchr(wsopts.ip, '*'))==NULL)
	ichkfn=mycmp;
    else
	ichkfn=match;

    if(wsopts.channel!=NULL)
    {
	if(IsMember(sptr,wsopts.channel) && (!(wsopts.channel->mode.mode & MODE_AUDITORIUM) ||
           is_chan_opvoice(sptr, wsopts.channel)))
	    showall=1;
	else if(SecretChannel(wsopts.channel) && IsAdmin(sptr))
	    showall=1;
	else if(!SecretChannel(wsopts.channel) && IsAnOper(sptr))
	    showall=1;
	else
	    showall=0;
	if(showall || !SecretChannel(wsopts.channel))
	{
	    for(cm=wsopts.channel->members; cm; cm=cm->next)
	    {
		ac=cm->cptr;
		i=0;
		if(!chk_who(ac,showall))
		    continue;
		/* If we have channel flags set, verify they match */
		if(wsopts.channelflags && ((cm->flags & wsopts.channelflags) == 0))
		    continue;
		/* get rid of the pidly stuff first */
		/* wow, they passed it all, give them the reply...
		 * IF they haven't reached the max, or they're an oper */
		status[i++]=(ac->user->away==NULL ? 'H' : 'G');
		status[i]=(IsAnOper(ac) ? '*' : ((IsInvisible(ac) &&
						  IsOper(sptr)) ? '%' : 0));
		status[((status[i]) ? ++i : i)]=((cm->flags&CHFL_CHANOP) ? '@'
						 : ((cm->flags&CHFL_VOICE) ? 
						    '+' : 0));
		status[++i]=0;
		sendto_one(sptr, getreply(RPL_WHOREPLY), me.name, sptr->name,
			   wsopts.channel->chname, ac->user->username,
			   WHO_HOST(ac), WHO_SERVER(sptr, ac), ac->name, status,
			   WHO_HOPCOUNT(sptr, ac),
			   ac->info);
	    }
	}
	sendto_one(sptr, getreply(RPL_ENDOFWHO), me.name, sptr->name,
		   wsopts.channel->chname, "WHO");
	return 0;
    }
    /* if (for whatever reason) they gave us a nick with no
     * wildcards, just do a find_person, bewm! */
    else if(nchkfn==mycmp)
    {
	ac=find_person(wsopts.nick,NULL);
	if(ac!=NULL)
	{
	    if(!chk_who(ac,1))
	    {
		sendto_one(sptr, getreply(RPL_ENDOFWHO), me.name, sptr->name,
			   wsopts.host!=NULL ? wsopts.host : wsopts.nick, "WHO");
		return 0;
	    }
	    else
	    {
		status[0]=(ac->user->away==NULL ? 'H' : 'G');
		status[1]=(IsAnOper(ac) ? '*' : (IsInvisible(ac) &&
						 IsAnOper(sptr) ? '%' : 0));
		status[2]=0;
		sendto_one(sptr, getreply(RPL_WHOREPLY), me.name, sptr->name,
			   wsopts.show_chan ? first_visible_channel(ac, sptr)
			   : "*", ac->user->username, WHO_HOST(ac),
			   WHO_SERVER(sptr, ac), ac->name, status,
			   WHO_HOPCOUNT(sptr, ac),
			   ac->info);
		sendto_one(sptr, getreply(RPL_ENDOFWHO), me.name, sptr->name,
			   wsopts.host!=NULL ? wsopts.host : wsopts.nick, "WHO");
		return 0;
	    }
	}
	sendto_one(sptr, getreply(RPL_ENDOFWHO), me.name, sptr->name,
		   wsopts.host!=NULL ? wsopts.host : wsopts.nick, "WHO");
	return 0;
    }
    
    if(wsopts.search_chan)
    {
	for(lp = sptr->user->channel; lp; lp = lp->next)
	{
	    for(cm = lp->value.chptr->members; cm; cm = cm->next)
	    {
		ac = cm->cptr;
		if(!chk_who(ac, 1))
		    continue;
		
		if(shown==MAXWHOREPLIES && !IsAnOper(sptr))
		{
		    sendto_one(sptr, getreply(ERR_WHOLIMEXCEED), me.name,
			       sptr->name, MAXWHOREPLIES, "WHO");
		    break;
		}
		
		i = 0;
		status[i++]=(ac->user->away==NULL ? 'H' : 'G');
		status[i]=(IsAnOper(ac) ? '*' : ((IsInvisible(ac) &&
						  IsOper(sptr)) ? '%' : 0));
		status[((status[i]) ? ++i : i)]=((cm->flags&CHFL_CHANOP) ? 
						 '@' : ((cm->flags&CHFL_VOICE)
							? '+' : 0));
		status[++i]=0;
		sendto_one(sptr, getreply(RPL_WHOREPLY), me.name, sptr->name,
			   lp->value.chptr->chname, ac->user->username,
			   WHO_HOST(ac),WHO_SERVER(sptr, ac), ac->name,
			   status, WHO_HOPCOUNT(sptr, ac), ac->info);
		shown++;
	    }
	}
    }
    else
    {
	for(ac=client;ac;ac=ac->next)
	{
	    if(!chk_who(ac,showall))
		continue;
	    /* wow, they passed it all, give them the reply...
	     * IF they haven't reached the max, or they're an oper */
	    if(shown==MAXWHOREPLIES && !IsAnOper(sptr))
	    {
		sendto_one(sptr, getreply(ERR_WHOLIMEXCEED), me.name, 
			   sptr->name, MAXWHOREPLIES, "WHO");
		break; /* break out of loop so we can send end of who */
	    }
	    status[0]=(ac->user->away==NULL ? 'H' : 'G');
	    status[1]=(IsAnOper(ac) ? '*' : (IsInvisible(ac) && 
					     IsAnOper(sptr) ? '%' : 0));
	    status[2]=0;
	    sendto_one(sptr, getreply(RPL_WHOREPLY), me.name, sptr->name,
		       wsopts.show_chan ? first_visible_channel(ac, sptr) :
		       "*", ac->user->username, WHO_HOST(ac),
		       WHO_SERVER(sptr, ac), ac->name, status,
		       WHO_HOPCOUNT(sptr, ac), ac->info);
	    shown++;
	}
    }
    sendto_one(sptr, getreply(RPL_ENDOFWHO), me.name, sptr->name,
	       (wsopts.host!=NULL ? wsopts.host :
		(wsopts.nick!=NULL ? wsopts.nick :
		 (wsopts.user!=NULL ? wsopts.user :
		  (wsopts.gcos!=NULL ? wsopts.gcos :
		   (wsopts.server!=NULL ? wsopts.server->name :
		    "*"))))), "WHO");
    return 0;
}
コード例 #2
0
ファイル: m_who.c プロジェクト: Adam-/unrealircd
static void do_other_who(aClient *sptr, char *mask)
{
int oper = IsAnOper(sptr);

	/* wildcard? */
#ifndef NO_FDLIST
	if (lifesux && !IsOper(sptr) && *mask == '*' && *(mask+1) == 0)
	{
		sendto_one(sptr, err_str(ERR_HTMDISABLED), me.name,
                    sptr->name, "/WHO");
		return;
	}
#endif		
	if (strchr(mask, '*') || strchr(mask, '?'))
	{
		int i = 0;
		/* go through all users.. */
		aClient *acptr;
		who_flags |= WF_WILDCARD;

		for (acptr = client; acptr; acptr = acptr->next)
		{
		int cansee;
		char status[20];
		char *channel;
		int flg;

			if (!IsPerson(acptr))
				continue;
			if (!oper) {
				/* non-opers can only search on nick here */
				if (match(mask, acptr->name))
					continue;
			} else {
				/* opers can search on name, ident, virthost, ip and realhost.
				 * Yes, I like readable if's -- Syzop.
				 */
				if (!match(mask, acptr->name) || !match(mask, acptr->user->realhost) ||
				    !match(mask, acptr->user->username))
					goto matchok;
				if (IsHidden(acptr) && !match(mask, acptr->user->virthost))
					goto matchok;
				if (acptr->user->ip_str && !match(mask, acptr->user->ip_str))
					goto matchok;
				/* nothing matched... */
				continue;
			}
matchok:
			if ((cansee = can_see(sptr, acptr, NULL)) & WHO_CANTSEE)
				continue;
			if (WHOLIMIT && !IsAnOper(sptr) && ++i > WHOLIMIT)
			{
				sendto_one(sptr, rpl_str(ERR_WHOLIMEXCEED), me.name, sptr->name, WHOLIMIT);
				return;
			}

			channel = first_visible_channel(sptr, acptr, &flg);
			make_who_status(sptr, acptr, NULL, NULL, status, cansee);
			send_who_reply(sptr, acptr, channel, status, (flg & FVC_HIDDEN) ? "~" : "");
		}
	}
	else
	{
		/* just a single client (no wildcards detected) */
		aClient *acptr = find_client(mask, NULL);
		int cansee;
		char status[20];
		char *channel;
		int flg;

		if (!acptr)
			return;

		if ((cansee = can_see(sptr, acptr, NULL)) == WHO_CANTSEE)
			return;

		channel = first_visible_channel(sptr, acptr, &flg);
		make_who_status(sptr, acptr, NULL, NULL, status, cansee);
		send_who_reply(sptr, acptr, channel, status, (flg & FVC_HIDDEN) ? "~" : "");
	}
}