Exemplo n.º 1
0
long get_access(aClient *cptr, aChannel *chptr)
{
	Membership *lp;
	if (chptr)
		if ((lp = find_membership_link(cptr->user->channel, chptr)))
			return lp->flags;
	return 0;
}
Exemplo n.º 2
0
int  is_chanprot(aClient *cptr, aChannel *chptr)
{
	Membership *lp;

	if (chptr)
		if ((lp = find_membership_link(cptr->user->channel, chptr)))
			return (lp->flags & CHFL_CHANPROT);

	return 0;
}
Exemplo n.º 3
0
int is_chanownprotop(aClient *cptr, aChannel *chptr) {
	Membership *lp;
		
	if (IsServer(cptr))
		return 1;
	if (chptr)
		if ((lp = find_membership_link(cptr->user->channel, chptr)))
			if (lp->flags & (CHFL_CHANOWNER|CHFL_CHANPROT|CHFL_CHANOP))
				return 1;
	return 0;
}
Exemplo n.º 4
0
int  is_chanowner(aClient *cptr, aChannel *chptr)
{
	Membership *lp;

	if (IsServer(cptr))
		return 1;
	if (chptr)
		if ((lp = find_membership_link(cptr->user->channel, chptr)))
			return (lp->flags & CHFL_CHANOWNER);

	return 0;
}
Exemplo n.º 5
0
int  has_voice(aClient *cptr, aChannel *chptr)
{
	Membership *lp;

	if (IsServer(cptr))
		return 1;
	if (chptr)
		if ((lp = find_membership_link(cptr->user->channel, chptr)))
			return (lp->flags & CHFL_VOICE);

	return 0;
}
Exemplo n.º 6
0
int  is_halfop(aClient *cptr, aChannel *chptr)
{
	Membership *lp;

	if (IsServer(cptr))
		return 1;
	if (chptr)
		if ((lp = find_membership_link(cptr->user->channel, chptr)))
			if (!(lp->flags & CHFL_CHANOP))
				return (lp->flags & CHFL_HALFOP);

	return 0;
}
Exemplo n.º 7
0
int is_skochanop(aClient *cptr, aChannel *chptr) {
	Membership *lp;
		
	if (IsServer(cptr))
		return 1;
	if (chptr)
		if ((lp = find_membership_link(cptr->user->channel, chptr)))
#ifdef PREFIX_AQ
			if (lp->flags & (CHFL_CHANOWNER|CHFL_CHANPROT|CHFL_CHANOP|CHFL_HALFOP))
#else
			if (lp->flags & (CHFL_CHANOP|CHFL_HALFOP))
#endif
				return 1;
	return 0;
}
Exemplo n.º 8
0
int  is_chan_op(aClient *cptr, aChannel *chptr)
{
	Membership *lp;
/* chanop/halfop ? */
	if (IsServer(cptr))
		return 1;
	if (chptr)
		if ((lp = find_membership_link(cptr->user->channel, chptr)))
#ifdef PREFIX_AQ
			return ((lp->flags & (CHFL_CHANOP|CHFL_CHANPROT|CHFL_CHANOWNER)));
#else
			return ((lp->flags & CHFL_CHANOP));
#endif

	return 0;
}
Exemplo n.º 9
0
/*
** m_part
**	parv[0] = sender prefix
**	parv[1] = channel
**	parv[2] = comment (added by Lefler)
*/
DLLFUNC CMD_FUNC(m_part)
{
	aChannel *chptr;
	Membership *lp;
	char *p = NULL, *name;
	char *commentx = (parc > 2 && parv[2]) ? parv[2] : NULL;
	char *comment;
	int n;
	
	if (parc < 2 || parv[1][0] == '\0')
	{
		sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS),
		    me.name, parv[0], "PART");
		return 0;
	}

	if (MyClient(sptr))
	{
		if (IsShunned(sptr))
			commentx = NULL;
		if (STATIC_PART)
		{
			if (!strcasecmp(STATIC_PART, "yes") || !strcmp(STATIC_PART, "1"))
				commentx = NULL;
			else if (!strcasecmp(STATIC_PART, "no") || !strcmp(STATIC_PART, "0"))
				; /* keep original reason */
			else
				commentx = STATIC_PART;
		}
		if (commentx)
		{
			n = dospamfilter(sptr, commentx, SPAMF_PART, parv[1], 0, NULL);
			if (n == FLUSH_BUFFER)
				return n;
			if (n < 0)
				commentx = NULL;
		}
	}

	for (; (name = strtoken(&p, parv[1], ",")); parv[1] = NULL)
	{
		chptr = get_channel(sptr, name, 0);
		if (!chptr)
		{
			sendto_one(sptr, err_str(ERR_NOSUCHCHANNEL),
			    me.name, parv[0], name);
			continue;
		}
		if (check_channelmask(sptr, cptr, name))
			continue;

		/* 'commentx' is the general part msg, but it can be changed
		 * per-channel (eg some chans block badwords, strip colors, etc)
		 * so we copy it to 'comment' and use that in this for loop :)
		 */
		comment = commentx;

		if (!(lp = find_membership_link(sptr->user->channel, chptr)))
		{
			/* Normal to get get when our client did a kick
			   ** for a remote client (who sends back a PART),
			   ** so check for remote client or not --Run
			 */
			if (MyClient(sptr))
				sendto_one(sptr,
				    err_str(ERR_NOTONCHANNEL), me.name,
				    parv[0], name);
			continue;
		}

		if (!IsAnOper(sptr) && !is_chanownprotop(sptr, chptr)) {
#ifdef STRIPBADWORDS
			int blocked = 0;
#endif
			/* Banned? No comment allowed ;) */
			if (comment && is_banned(sptr, chptr, BANCHK_MSG))
				comment = NULL;
			/* And other things... */
			if ((chptr->mode.mode & MODE_NOCOLOR) && comment) {
				if (strchr((char *)comment, 3) || strchr((char *)comment, 27)) {
					comment = NULL;
				}
			}
			if ((chptr->mode.mode & MODE_MODERATED) && comment &&
				 !has_voice(sptr, chptr) && !is_halfop(sptr, chptr))
			{
				comment = NULL;
			}
			if ((chptr->mode.mode & MODE_STRIP) && comment) {
				comment = (char *)StripColors(comment);
			}
#ifdef STRIPBADWORDS
 #ifdef STRIPBADWORDS_CHAN_ALWAYS
			if (comment)
			{
				comment = (char *)stripbadwords_channel(comment, &blocked);
			}
 #else
			if ((chptr->mode.extmode & EXTMODE_STRIPBADWORDS) && comment) {
				comment = (char *)stripbadwords_channel(comment, &blocked);
			}
 #endif
#endif
			
		}
		/* +M and not logged in to services? */
		if ((chptr->mode.mode & MODE_MODREG) && !IsLoggedIn(sptr) && !IsAnOper(sptr))
			comment = NULL;

		if (MyConnect(sptr))
		{
			Hook *tmphook;
			for (tmphook = Hooks[HOOKTYPE_PRE_LOCAL_PART]; tmphook; tmphook = tmphook->next) {
				comment = (*(tmphook->func.pcharfunc))(sptr, chptr, comment);
				if (!comment)
					break;
			}
		}

		/* Send to other servers... */
		if (!comment)
			sendto_serv_butone_token(cptr, parv[0],
			    MSG_PART, TOK_PART, "%s", chptr->chname);
		else
			sendto_serv_butone_token(cptr, parv[0],
			    MSG_PART, TOK_PART, "%s :%s", chptr->chname,
			    comment);

		if (1)
		{
			if ((chptr->mode.mode & MODE_AUDITORIUM) && !is_chanownprotop(sptr, chptr))
			{
				if (!comment)
				{
					sendto_chanops_butone(NULL,
					    chptr, ":%s!%s@%s PART %s",
					    sptr->name, sptr->user->username, GetHost(sptr),
					    chptr->chname);
					if (!is_chan_op(sptr, chptr) && MyClient(sptr))
						sendto_one(sptr, ":%s!%s@%s PART %s",
						    sptr->name, sptr->user->username, GetHost(sptr), chptr->chname);
				}
				else
				{
					sendto_chanops_butone(NULL,
					    chptr,
					    ":%s!%s@%s PART %s %s",
					    sptr->name,
					    sptr->user->username,
					    GetHost(sptr),
					    chptr->chname, comment);
					if (!is_chan_op(cptr, chptr) && MyClient(sptr))
						sendto_one(sptr,
						    ":%s!%s@%s PART %s %s",
						    sptr->name, sptr->user->username, GetHost(sptr),
						    chptr->chname, comment);
				}
			}
			else
			{


				if (!comment)

					sendto_channel_butserv(chptr,
					    sptr, PARTFMT, parv[0],
					    chptr->chname);
				else
					sendto_channel_butserv(chptr,
					    sptr, PARTFMT2, parv[0],
					    chptr->chname, comment);
			}
			if (MyClient(sptr))
				RunHook4(HOOKTYPE_LOCAL_PART, cptr, sptr, chptr, comment);
			else
				RunHook4(HOOKTYPE_REMOTE_PART, cptr, sptr, chptr, comment);

			remove_user_from_channel(sptr, chptr);
		}
	}
	return 0;
}
Exemplo n.º 10
0
int  can_send(aClient *cptr, aChannel *chptr, char *msgtext, int notice)
{
	Membership *lp;
	int  member;
	/* 
	 * #0000053 by |savage|, speedup 
	*/
	
	if (!MyClient(cptr))
	{
		if (IsClient(cptr))
		{
			/* channelmode +mu is a special case.. sux!. -- Syzop */		

			lp = find_membership_link(cptr->user->channel, chptr);
			if ((chptr->mode.mode & MODE_MODERATED) && (chptr->mode.mode & MODE_AUDITORIUM) &&
			    !IsOper(cptr) &&
		        (!lp || !(lp->flags & (CHFL_CHANOP|CHFL_VOICE|CHFL_CHANOWNER|CHFL_HALFOP|CHFL_CHANPROT))) &&
		        !is_irc_banned(chptr))
		    {
				sendto_chmodemucrap(cptr, chptr, msgtext);
				return (CANNOT_SEND_MODERATED);
			}
		}
		return 0;
	}

	if (chptr->mode.mode & MODE_NOCOLOR)
	{
		/* A bit faster */
		char *c;
		for (c = msgtext; *c; c++)
		{
			if (*c == 3 || *c == 27 || *c == 4 || *c == 22) /* mirc color, ansi, rgb, reverse */
				return (CANNOT_SEND_NOCOLOR);
		}
	}
	member = IsMember(cptr, chptr);
	if (chptr->mode.mode & MODE_NOPRIVMSGS && !member)
		return (CANNOT_SEND_NOPRIVMSGS);

	lp = find_membership_link(cptr->user->channel, chptr);
	if ((chptr->mode.mode & MODE_MODREG) && !op_can_override(cptr) && !IsRegNick(cptr) && 
	    (!lp
	    || !(lp->flags & (CHFL_CHANOP | CHFL_VOICE | CHFL_CHANOWNER |
	    CHFL_HALFOP | CHFL_CHANPROT))))
		return CANNOT_SEND_MODREG;
	if (chptr->mode.mode & MODE_MODERATED && !op_can_override(cptr) &&
	    (!lp
	    || !(lp->flags & (CHFL_CHANOP | CHFL_VOICE | CHFL_CHANOWNER |
	    CHFL_HALFOP | CHFL_CHANPROT))))
	    {
			if ((chptr->mode.mode & MODE_AUDITORIUM) && !is_irc_banned(chptr) && !is_banned(cptr, chptr, BANCHK_MSG))
				sendto_chmodemucrap(cptr, chptr, msgtext);
			return (CANNOT_SEND_MODERATED);
	    }

	if (chptr->mode.mode & MODE_NOCTCP &&
	    (!lp
	    || !(lp->flags & (CHFL_CHANOP | CHFL_CHANOWNER | CHFL_CHANPROT))))
		if (msgtext[0] == 1 && strncmp(&msgtext[1], "ACTION ", 7))
			return (CANNOT_SEND_NOCTCP);

#ifdef EXTCMODE
	if (notice && (chptr->mode.extmode & EXTMODE_NONOTICE) &&
	   (!lp || !(lp->flags & (CHFL_CHANOP | CHFL_CHANOWNER | CHFL_CHANPROT))))
		return (CANNOT_SEND_NOTICE);
#endif


	/* Makes opers able to talk thru bans -Stskeeps suggested by The_Cat */
	if (IsOper(cptr))
		return 0;

	if ((!lp
	    || !(lp->flags & (CHFL_CHANOP | CHFL_VOICE | CHFL_CHANOWNER |
	    CHFL_HALFOP | CHFL_CHANPROT))) && MyClient(cptr)
	    && is_banned(cptr, chptr, BANCHK_MSG))
		return (CANNOT_SEND_BAN);

	return 0;
}
Exemplo n.º 11
0
int  check_for_chan_flood(aClient *cptr, aClient *sptr, aChannel *chptr)
{
	Membership *lp;
	MembershipL *lp2;
	int c_limit, t_limit, banthem;

	if (!MyClient(sptr))
		return 0;
	if (IsOper(sptr) || IsULine(sptr))
		return 0;
	if (is_skochanop(sptr, chptr))
		return 0;

	if (!(lp = find_membership_link(sptr->user->channel, chptr)))
		return 0;

	lp2 = (MembershipL *) lp;

#ifdef NEWCHFLOODPROT
	if (!chptr->mode.floodprot || !chptr->mode.floodprot->l[FLD_TEXT])
		return 0;
	c_limit = chptr->mode.floodprot->l[FLD_TEXT];
	t_limit = chptr->mode.floodprot->per;
	banthem = (chptr->mode.floodprot->a[FLD_TEXT] == 'b') ? 1 : 0;
#else
	if ((chptr->mode.msgs < 1) || (chptr->mode.per < 1))
		return 0;
	c_limit = chptr->mode.msgs;
	t_limit = chptr->mode.per;
	banthem = chptr->mode.kmode;
#endif
	/* if current - firstmsgtime >= mode.per, then reset,
	 * if nummsg > mode.msgs then kick/ban
	 */
	Debug((DEBUG_ERROR, "Checking for flood +f: firstmsg=%d (%ds ago), new nmsgs: %d, limit is: %d:%d",
		lp2->flood.firstmsg, TStime() - lp2->flood.firstmsg, lp2->flood.nmsg + 1,
		c_limit, t_limit));
	if ((TStime() - lp2->flood.firstmsg) >= t_limit)
	{
		/* reset */
		lp2->flood.firstmsg = TStime();
		lp2->flood.nmsg = 1;
		return 0; /* forget about it.. */
	}

	/* increase msgs */
	lp2->flood.nmsg++;

	if ((lp2->flood.nmsg) > c_limit)
	{
		char comment[1024], mask[1024];
		ircsprintf(comment,
		    "Flooding (Limit is %i lines per %i seconds)",
		    c_limit, t_limit);
		if (banthem)
		{		/* ban. */
			ircsprintf(mask, "*!*@%s", GetHost(sptr));
			add_listmode(&chptr->banlist, &me, chptr, mask);
			sendto_serv_butone(&me, ":%s MODE %s +b %s 0",
			    me.name, chptr->chname, mask);
			sendto_channel_butserv(chptr, &me,
			    ":%s MODE %s +b %s", me.name, chptr->chname, mask);
		}
		sendto_channel_butserv(chptr, &me,
		    ":%s KICK %s %s :%s", me.name,
		    chptr->chname, sptr->name, comment);
		sendto_serv_butone_token(cptr, me.name,
			MSG_KICK, TOK_KICK, 
			"%s %s :%s",
		   chptr->chname, sptr->name, comment);
		remove_user_from_channel(sptr, chptr);
		return 1;
	}
	return 0;
}
Exemplo n.º 12
0
/* m_sajoin() - Lamego - Wed Jul 21 20:04:48 1999
   Copied off PTlink IRCd (C) PTlink coders team.
   Coded for Sadmin by Stskeeps
   also Modified by NiQuiL ([email protected])
	parv[0] - sender
	parv[1] - nick to make join
	parv[2] - channel(s) to join
*/
DLLFUNC CMD_FUNC(m_sajoin)
{
	aClient *acptr;
	char jbuf[BUFSIZE];
	int did_anything = 0;

	if (!IsSAdmin(sptr) && !IsULine(sptr))
	{
	 sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
	 return 0;
	}

	if (parc < 3)
	{
	 sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "SAJOIN");
	 return 0;
	}

	if (!(acptr = find_person(parv[1], NULL)))
	{
		sendto_one(sptr, err_str(ERR_NOSUCHNICK), me.name, parv[0], parv[1]);
		return 0;
	}
	if (MyClient(acptr))
	{
		char *name, *p = NULL;
		int i, parted = 0;
	
		*jbuf = 0;

		/* Now works like m_join */
		for (i = 0, name = strtoken(&p, parv[2], ","); name; name = strtoken(&p,
		     NULL, ","))
		{
			aChannel *chptr;
			Membership *lp;

			if (strlen(name) > CHANNELLEN)
				name[CHANNELLEN] = 0;
			clean_channelname(name);
			if (*name == '0' && !atoi(name))
			{
				(void)strcpy(jbuf, "0");
				i = 1;
				parted = 1;
				continue;
			}
			if (check_channelmask(sptr, cptr, name) == -1 || *name == '0' ||
			    !IsChannelName(name))
			{
				sendto_one(sptr,
				    err_str(ERR_NOSUCHCHANNEL), me.name,
				    parv[0], name);
				continue;
			}

			chptr = get_channel(acptr, name, 0);
			if (!parted && chptr && (lp = find_membership_link(acptr->user->channel, chptr)))
			{
				sendto_one(sptr, err_str(ERR_USERONCHANNEL), me.name, parv[0], 
					   parv[1], name);
				continue;
			}
			if (*jbuf)
				(void)strlcat(jbuf, ",", sizeof jbuf);
			(void)strlncat(jbuf, name, sizeof jbuf, sizeof(jbuf) - i - 1);
			i += strlen(name) + 1;
		}
		if (!*jbuf)
			return -1;
		i = 0;
		strcpy(parv[2], jbuf);
		*jbuf = 0;
		for (name = strtoken(&p, parv[2], ","); name; name = strtoken(&p, NULL, ","))
		{
			int flags;
			aChannel *chptr;
			Membership *lp;

			if (*name == '0' && !atoi(name))
			{
				did_anything = 1;
				while ((lp = acptr->user->channel))
				{
					chptr = lp->chptr;
					sendto_channel_butserv(chptr, acptr,
					    ":%s PART %s :%s", acptr->name, chptr->chname,
					    "Left all channels");
					if (MyConnect(acptr))
						RunHook4(HOOKTYPE_LOCAL_PART, acptr, acptr, chptr,
							 "Left all channels");
					remove_user_from_channel(acptr, chptr);
				}
				sendto_serv_butone_token(acptr, acptr->name,
				    MSG_JOIN, TOK_JOIN, "0");
				strcpy(jbuf, "0");
				i = 1;
				continue;
			}
			flags = (ChannelExists(name)) ? CHFL_DEOPPED : CHFL_CHANOP;
			chptr = get_channel(acptr, name, CREATE);
			if (chptr && (lp = find_membership_link(acptr->user->channel, chptr)))
				continue;
			if ((chptr->mode.mode & MODE_ONLYSECURE) && !IsSecure(acptr))
			{
				sendnotice(sptr, "You cannot SAJOIN %s to %s because the channel is +z and the user is not connected via SSL",
					acptr->name, chptr->chname);
				continue;
			}
			join_channel(chptr, acptr, acptr, flags);
			did_anything = 1;
			if (*jbuf)
				(void)strlcat(jbuf, ",", sizeof jbuf);
			(void)strlncat(jbuf, name, sizeof jbuf, sizeof(jbuf) - i - 1);
			i += strlen(name) + 1;
		}
		
		if (did_anything)
		{
			sendnotice(acptr, "*** You were forced to join %s", jbuf);
			sendto_realops("%s used SAJOIN to make %s join %s", sptr->name, acptr->name,
				       jbuf);
			sendto_serv_butone(&me, ":%s GLOBOPS :%s used SAJOIN to make %s join %s",
					   me.name, sptr->name, acptr->name, jbuf);
			/* Logging function added by XeRXeS */
			ircd_log(LOG_SACMDS,"SAJOIN: %s used SAJOIN to make %s join %s",
				sptr->name, parv[1], jbuf);
		}
	}
	else
	{
		sendto_one(acptr, ":%s SAJOIN %s %s", parv[0],
		    parv[1], parv[2]);

		/* Logging function added by XeRXeS */
		ircd_log(LOG_SACMDS,"SAJOIN: %s used SAJOIN to make %s join %s",
			sptr->name, parv[1], parv[2]);
	}

	return 0;
}
Exemplo n.º 13
0
DLLFUNC CMD_FUNC(m_sapart)
{
	aClient *acptr;
	aChannel *chptr;
	Membership *lp;
	char *name, *p = NULL;
	int i;
	char *comment = (parc > 3 && parv[3] ? parv[3] : NULL);
	char commentx[512];
	char jbuf[BUFSIZE];

	if (!IsSAdmin(sptr) && !IsULine(sptr))
	{
		sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
		return 0;
	}

	if (parc < 3)
	{
		sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "SAPART");
		return 0;
	}

	if (!(acptr = find_person(parv[1], NULL)))
	{
		sendto_one(sptr, err_str(ERR_NOSUCHNICK), me.name, parv[0], parv[1]);
		return 0;
	}

	if (MyClient(acptr))
	{
		/* Now works like m_join */
		*jbuf = 0;

		for (i = 0, name = strtoken(&p, parv[2], ","); name; name = strtoken(&p,
			NULL, ","))
		{
			if (!(chptr = get_channel(acptr, name, 0)))
			{
				sendto_one(sptr, err_str(ERR_NOSUCHCHANNEL), me.name, parv[0],
					name);
				continue;
			}
			if (!(lp = find_membership_link(acptr->user->channel, chptr)))
			{
				sendto_one(sptr, err_str(ERR_USERNOTINCHANNEL), me.name, parv[0],
					parv[1], name);
				continue;
			}
			if (*jbuf)
				(void)strlcat(jbuf, ",", sizeof jbuf);
			(void)strlncat(jbuf, name, sizeof jbuf, sizeof(jbuf) - i - 1);
			i += strlen(name) + 1;
		}

		if (!*jbuf)
			return -1;

		strcpy(parv[2], jbuf);

		if (comment)
		{
			strcpy(commentx, "SAPart: ");
			strlcat(commentx, comment, 512);
		}

		parv[0] = parv[1]; // nick
		parv[1] = parv[2]; // chan
		parv[2] = comment ? commentx : NULL; // comment
		if (comment)
		{
			sendnotice(acptr,
			    "*** You were forced to part %s (%s)",
			    parv[1], commentx);
			sendto_realops("%s used SAPART to make %s part %s (%s)", sptr->name, parv[0],
				parv[1], comment);
			sendto_server(&me, 0, 0, ":%s GLOBOPS :%s used SAPART to make %s part %s (%s)",
				me.name, sptr->name, parv[0], parv[1], comment);
			/* Logging function added by XeRXeS */
			ircd_log(LOG_SACMDS,"SAPART: %s used SAPART to make %s part %s (%s)",
				sptr->name, parv[0], parv[1], comment);
		}
		else
		{
			sendnotice(acptr,
			    "*** You were forced to part %s", parv[1]);
			sendto_realops("%s used SAPART to make %s part %s", sptr->name, parv[0],
				parv[1]);
			sendto_server(&me, 0, 0, ":%s GLOBOPS :%s used SAPART to make %s part %s",
				me.name, sptr->name, parv[0], parv[1]);
			/* Logging function added by XeRXeS */
			ircd_log(LOG_SACMDS,"SAPART: %s used SAPART to make %s part %s",
				sptr->name, parv[0], parv[1]);
		}
		do_cmd(acptr, acptr, "PART", comment ? 3 : 2, parv);
	}
	else
	{
		if (comment)
		{
			sendto_one(acptr, ":%s SAPART %s %s :%s", parv[0],
			    parv[1], parv[2], comment);
			/* Logging function added by XeRXeS */
			ircd_log(LOG_SACMDS,"SAPART: %s used SAPART to make %s part %s (%s)",
				sptr->name, parv[1], parv[2], comment);
		}
		else
		{
			sendto_one(acptr, ":%s SAPART %s %s", parv[0], parv[1],
				   parv[2]);
			/* Logging function added by XeRXeS */
			ircd_log(LOG_SACMDS,"SAPART: %s used SAPART to make %s part %s",
				sptr->name, parv[1], parv[2]);
		}
	}

	return 0;
}