text: /*
   * speech.c -- Commands which involve speaking 
   */
  
  #include "copyright.h"
  #include "config.h"
  
  #include "mudconf.h"
  #include "config.h"
  #include "db.h"
  #include "interface.h"
  #include "match.h"
  #include "externs.h"
  #include "flags.h"
  #include "powers.h"
  #include "attrs.h"
  #include "alloc.h"
  
  extern char *next_token(char *, char);
  extern int In_IC_Loc(dbref);
  
  int sp_ok(dbref player)
  {
  	if(Gagged(player) && (!(Wizard(player)))) {
  		notify(player, "Sorry. Gagged players cannot speak.");
  		return 0;
  	}
  
  	if(!mudconf.robot_speak) {
  		if(Robot(player) && !controls(player, Location(player))) {
  			notify(player, "Sorry robots may not speak in public.");
  			return 0;
  		}
  	}
  	if(Auditorium(Location(player))) {
  		if(!could_doit(player, Location(player), A_LSPEECH)) {
  			notify(player, "Sorry, you may not speak in this place.");
  			return 0;
  		}
  	}
  	return 1;
  }
  
  static void say_shout(int target, const char *prefix, int flags, dbref player,
  					  char *message)
  {
  	if(flags & SAY_NOTAG)
  		raw_broadcast(target, "%s%s", Name(player), message);
  	else
  		raw_broadcast(target, "%s%s%s", prefix, Name(player), message);
  }
  
  static const char *announce_msg = "Announcement: ";
  static const char *broadcast_msg = "Broadcast: ";
  static const char *admin_msg = "Admin: ";
  
  void do_think(dbref player, dbref cause, int key, char *message)
  {
  	char *str, *buf, *bp;
  
  	buf = bp = alloc_lbuf("do_think");
  	str = message;
  	exec(buf, &bp, 0, player, cause, EV_FCHECK | EV_EVAL | EV_TOP, &str,
  		 (char **) NULL, 0);
  	*bp = '\0';
  	notify(player, buf);
  	free_lbuf(buf);
  }
  
  void do_say(dbref player, dbref cause, int key, char *message)
  {
  	dbref loc;
  	char *buf2, *bp;
  	int say_flags, depth;
  
  	/*
  	 * Convert prefix-coded messages into the normal type 
  	 */
  
  	say_flags = key & (SAY_NOTAG | SAY_HERE | SAY_ROOM );
  	key &= ~(SAY_NOTAG | SAY_HERE | SAY_ROOM );
  
  	if(key == SAY_PREFIX) {
  		switch (*message++) {
  		case '"':
  			key = SAY_SAY;
  			break;
  		case ':':
  			if(*message == ' ') {
  				message++;
  				key = SAY_POSE_NOSPC;
  			} else {
  				key = SAY_POSE;
  			}
  			break;
  		case ';':
  			key = SAY_POSE_NOSPC;
  			break;
  		case '\\':
  			key = SAY_EMIT;
  			break;
  		default:
  			return;
  		}
  	}
  	/*
  	 * Make sure speaker is somewhere if speaking in a place 
  	 */
  
  	loc = where_is(player);
  	switch (key) {
  	case SAY_SAY:
  	case SAY_POSE:
  	case SAY_POSE_NOSPC:
  	case SAY_EMIT:
  		if(loc == NOTHING)
  			return;
  		if(!sp_ok(player))
  			return;
  	}
  
  	/*
  	 * Send the message on its way  
  	 */
  
  	switch (key) {
  	case SAY_SAY:
  		notify_printf(player, "You say \"%s\"", message);
  		notify_except(loc, player, player, tprintf("%s says \"%s\"",
  												   Name(player), message));
  		break;
  	case SAY_POSE:
  		notify_all_from_inside(loc, player, tprintf("%s %s", Name(player),
  													message));
  		break;
  	case SAY_POSE_NOSPC:
  		notify_all_from_inside(loc, player, tprintf("%s%s", Name(player),
  													message));
  		break;
  	case SAY_EMIT:
  		if((say_flags & SAY_HERE) || !say_flags) {
  			notify_all_from_inside(loc, player, message);
  		}
  		if(say_flags & SAY_ROOM) {
  			if((Typeof(loc) == TYPE_ROOM) && (say_flags & SAY_HERE)) {
  				return;
  			}
  			depth = 0;
  			while ((Typeof(loc) != TYPE_ROOM) && (depth++ < 20)) {
  				loc = Location(loc);
  				if((loc == NOTHING) || (loc == Location(loc)))
  					return;
  			}
  			if(Typeof(loc) == TYPE_ROOM) {
  				notify_all_from_inside(loc, player, message);
  			}
  		}
  		break;
  	case SAY_SHOUT:
  		switch (*message) {
  		case ':':
  			message[0] = ' ';
  			say_shout(0, announce_msg, say_flags, player, message);
  			break;
  		case ';':
  			message++;
  			say_shout(0, announce_msg, say_flags, player, message);
  			break;
  		case '"':
  			message++;
  		default:
  			buf2 = alloc_lbuf("do_say.shout");
  			bp = buf2;
  			safe_str((char *) " shouts \"", buf2, &bp);
  			safe_str(message, buf2, &bp);
  			safe_chr('"', buf2, &bp);
  			*bp = '\0';
  			say_shout(0, announce_msg, say_flags, player, buf2);
  			free_lbuf(buf2);
  		}
  		STARTLOG(LOG_SHOUTS, "WIZ", "SHOUT") {
  			log_name(player);
  			buf2 = alloc_lbuf("do_say.LOG.shout");
  			sprintf(buf2, " shouts: '%s'", message);
  			log_text(buf2);
  			free_lbuf(buf2);
  			ENDLOG;
  		} break;
  
  	case SAY_WIZSHOUT:
  		switch (*message) {
  		case ':':
  			message[0] = ' ';
  			say_shout(WIZARD, broadcast_msg, say_flags, player, message);
  			break;
  		case ';':
  			message++;
  			say_shout(WIZARD, broadcast_msg, say_flags, player, message);
  			break;
  		case '"':
  			message++;
  		default:
  			buf2 = alloc_lbuf("do_say.wizshout");
  			bp = buf2;
  			safe_str((char *) " says \"", buf2, &bp);
  			safe_str(message, buf2, &bp);
  			safe_chr('"', buf2, &bp);
  			*bp = '\0';
  			say_shout(WIZARD, broadcast_msg, say_flags, player, buf2);
  			free_lbuf(buf2);
  		}
  		STARTLOG(LOG_SHOUTS, "WIZ", "BCAST") {
  			log_name(player);
  			buf2 = alloc_lbuf("do_say.LOG.wizshout");
  			sprintf(buf2, " broadcasts: '%s'", message);
  			log_text(buf2);
  			free_lbuf(buf2);
  			ENDLOG;
  		} break;
  
  	case SAY_ADMINSHOUT:
  		switch (*message) {
  		case ':':
  			message[0] = ' ';
  			say_shout(WIZARD, admin_msg, say_flags, player, message);
  			say_shout(ROYALTY, admin_msg, say_flags, player, message);
  			break;
  		case ';':
  			message++;
  			say_shout(WIZARD, admin_msg, say_flags, player, message);
  			say_shout(ROYALTY, admin_msg, say_flags, player, message);
  			break;
  		case '"':
  			message++;
  		default:
  			buf2 = alloc_lbuf("do_say.adminshout");
  			bp = buf2;
  			safe_str((char *) " says \"", buf2, &bp);
  			safe_str(message, buf2, &bp);
  			safe_chr('"', buf2, &bp);
  			*bp = '\0';
  			say_shout(WIZARD, admin_msg, say_flags, player, buf2);
  			say_shout(ROYALTY, admin_msg, say_flags, player, buf2);
  			free_lbuf(buf2);
  		}
  		STARTLOG(LOG_SHOUTS, "WIZ", "ASHOUT") {
  			log_name(player);
  			buf2 = alloc_lbuf("do_say.LOG.adminshout");
  			sprintf(buf2, " yells: '%s'", message);
  			log_text(buf2);
  			free_lbuf(buf2);
  			ENDLOG;
  		} break;
  
  	case SAY_WALLPOSE:
  		if(say_flags & SAY_NOTAG)
  			raw_broadcast(0, "%s %s", Name(player), message);
  		else
  			raw_broadcast(0, "Announcement: %s %s", Name(player), message);
  		STARTLOG(LOG_SHOUTS, "WIZ", "SHOUT") {
  			log_name(player);
  			buf2 = alloc_lbuf("do_say.LOG.wallpose");
  			sprintf(buf2, " WALLposes: '%s'", message);
  			log_text(buf2);
  			free_lbuf(buf2);
  			ENDLOG;
  		}
  		break;
  
  	case SAY_WIZPOSE:
  		if(say_flags & SAY_NOTAG)
  			raw_broadcast(WIZARD, "%s %s", Name(player), message);
  		else
  			raw_broadcast(WIZARD, "Broadcast: %s %s", Name(player), message);
  		STARTLOG(LOG_SHOUTS, "WIZ", "BCAST") {
  			log_name(player);
  			buf2 = alloc_lbuf("do_say.LOG.wizpose");
  			sprintf(buf2, " WIZposes: '%s'", message);
  			log_text(buf2);
  			free_lbuf(buf2);
  			ENDLOG;
  		}
  		break;
  
  	case SAY_WALLEMIT:
  		if(say_flags & SAY_NOTAG)
  			raw_broadcast(0, "%s", message);
  		else
  			raw_broadcast(0, "Announcement: %s", message);
  		STARTLOG(LOG_SHOUTS, "WIZ", "SHOUT") {
  			log_name(player);
  			buf2 = alloc_lbuf("do_say.LOG.wallemit");
  			sprintf(buf2, " WALLemits: '%s'", message);
  			log_text(buf2);
  			free_lbuf(buf2);
  			ENDLOG;
  		}
  		break;
  
  	case SAY_WIZEMIT:
  		if(say_flags & SAY_NOTAG)
  			raw_broadcast(WIZARD, "%s", message);
  		else
  			raw_broadcast(WIZARD, "Broadcast: %s", message);
  		STARTLOG(LOG_SHOUTS, "WIZ", "BCAST") {
  			log_name(player);
  			buf2 = alloc_lbuf("do_say.LOG.wizemit");
  			sprintf(buf2, " WIZemit: '%s'", message);
  			log_text(buf2);
  			free_lbuf(buf2);
  			ENDLOG;
  		}
  		break;
  	}
  }
  
  /*
   * ---------------------------------------------------------------------------
   * * do_page: Handle the page command.
   * * Page-pose code from shadow@prelude.cc.purdue.
   */
  
  static void page_return(dbref player, dbref target, const char *tag, int anum,
  						const char *dflt)
  {
  	dbref aowner;
  	int aflags;
  	char *str, *str2, *buf, *bp;
  	struct tm *tp;
  	time_t t;
  
  	str = atr_pget(target, anum, &aowner, &aflags);
  	if(*str) {
  		str2 = bp = alloc_lbuf("page_return");
  		buf = str;
  		exec(str2, &bp, 0, target, player,
  			 EV_FCHECK | EV_EVAL | EV_TOP | EV_NO_LOCATION, &buf,
  			 (char **) NULL, 0);
  		*bp = '\0';
  		if(*str2) {
  			t = time(NULL);
  			tp = localtime(&t);
  			if(Wizard(target) || !In_IC_Loc(target))
  				notify_with_cause(player, target,
  								  tprintf("%s message from %s: %s", tag,
  										  Name(target), str2));
  			notify_with_cause(target, player,
  							  tprintf("[%d:%02d] %s message sent to %s.",
  									  tp->tm_hour, tp->tm_min, tag,
  									  Name(player)));
  		}
  		free_lbuf(str2);
  	} else if(dflt && *dflt) {
  		notify_with_cause(player, target, dflt);
  	}
  	free_lbuf(str);
  }
  
  static int page_check(dbref player, dbref target)
  {
  	if(!payfor(player, Guest(player) ? 0 : mudconf.pagecost)) {
  		notify_printf(player, "You don't have enough %s.",
  					  mudconf.many_coins);
  		return 0;
  	}
  	if(In_IC_Loc(player) && !Wizard(target) && !Wizard(player)) {
  		notify(player, "Permission denied.");
  		return 0;
  	}
  	if(!Connected(target)) {
  		page_return(player, target, "Away", A_AWAY,
  					tprintf("Sorry, %s is not connected.", Name(target)));
  		return 0;
  	}
  	if(!could_doit(player, target, A_LPAGE) || (!Wizard(player) &&
  												In_IC_Loc(target)
  												&& !Wizard(target))) {
  		if(Wizard(target) && Dark(target))
  			page_return(player, target, "Away", A_AWAY,
  						tprintf("Sorry, %s is not connected.", Name(target)));
  		else
  			page_return(player, target, "Reject", A_REJECT,
  						tprintf("Sorry, %s is not accepting pages.",
  								Name(target)));
  		return 0;
  	}
  	if(!could_doit(target, player, A_LPAGE)) {
  		if(Wizard(player)) {
  			notify_printf(player, "Warning: %s can't return your page.",
  						  Name(target));
  			return 1;
  		} else {
  			notify_printf(player, "Sorry, %s can't return your page.",
  						  Name(target));
  			return 0;
  		}
  	}
  	return 1;
  }
  
  /*
   * Used in do_page 
   */
  static char *dbrefs_to_names(dbref player, char *list, char *namelist,
  							 int ismessage)
  {
  	char *bp, *p;
  	char oldlist[LBUF_SIZE];
  
  	StringCopy(oldlist, list);
  	bp = namelist;
  	for(p = (char *) strtok(oldlist, " "); p != NULL;
  		p = (char *) strtok(NULL, " ")) {
  		if(ismessage)
  			safe_str(tprintf("%s, ", Name(atoi(p))), namelist, &bp);
  		else {
  			if(lookup_player(player, p, 1) != NOTHING) {
  				safe_str(tprintf("%s, ", Name(lookup_player(player, p,
  															1))), namelist,
  						 &bp);
  			}
  		}
  	}
  	*(bp - 2) = '\0';
  	return bp;
  }
  
  void do_page(dbref player, dbref cause, int key, char *tname, char *message)
  {
  	dbref target, aowner;
  	char *p, *buf1, *bp, *buf2, *bp2, *mp, *str;
  	char targetname[LBUF_SIZE];
  	char alias[LBUF_SIZE];
  	char aladd[LBUF_SIZE];
  	int ispose = 0;
  	int ismessage = 0;
  	int count = 0;
  	int n = 0;
  	int aflags = 0;
  
  	buf1 = alloc_lbuf("page_return_list");
  	bp = buf1;
  
  	buf2 = alloc_lbuf("page_list");
  	bp2 = buf2;
  
  	if((tname[0] == ':') || (tname[0] == ';') || (message[0] == ':') ||
  	   (message[0] == ';'))
  		ispose = 1;
  
  	mp = message;
  
  	if(!*message) {
  		atr_get_str(targetname, player, A_LASTPAGE, &aowner, &aflags);
  		if(!*tname) {
  			if(!*targetname)
  				notify(player, "You have not paged anyone.");
  			else
  				for(p = (char *) strtok(targetname, " "); p != NULL;
  					p = (char *) strtok(NULL, " ")) {
  					target = atoi(p);
  					notify_printf(player, "You last paged %s.", Name(target));
  				}
  
  			free_lbuf(buf1);
  			free_lbuf(buf2);
  			return;
  		}
  		StringCopy(message, tname);
  		StringCopy(tname, targetname);
  		ismessage = 1;
  	}
  
  	atr_get_str(alias, player, A_ALIAS, &aowner, &aflags);
  	if(*alias)
  		sprintf(aladd, " (%s)", alias);
  	else
  		aladd[0] = 0;
  
  	/*
  	 * Count the words 
  	 */
  	for(n = 0, str = tname; str; str = (char *) next_token(str, ' '), n++);
  
  	if(((target = lookup_player(player, tname, 1)) == NOTHING) && n > 1) {
  		bp = dbrefs_to_names(player, tname, buf1, ismessage);
  		for(p = (char *) strtok(tname, " "); p != NULL;
  			p = (char *) strtok(NULL, " ")) {
  
  			/*
  			 * If it's a memory page, grab the number from the *
  			 * * * list 
  			 */
  			if(ismessage) {
  				target = atoi(p);
  			} else
  				target = lookup_player(player, p, 1);
  
  			message = mp;
  
  			if(target == NOTHING) {
  				notify_printf(player, "I don't recognize \"%s\".", p);
  			} else if(!page_check(player, target)) {
  				;
  			} else {
  				switch (*message) {
  				case ':':
  					notify_with_cause(target, player,
  									  tprintf("From afar, to (%s):%s %s %s",
  											  buf1, aladd, Name(player),
  											  message + 1));
  					break;
  				case ';':
  					message++;
  					notify_with_cause(target, player,
  									  tprintf("From afar, to (%s):%s %s%s",
  											  buf1, aladd, Name(player),
  											  message));
  					break;
  				case '"':
  					message++;
  				default:
  					notify_with_cause(target, player,
  									  tprintf("To (%s), %s%s pages you: %s",
  											  buf1, Name(player), aladd,
  											  message));
  				}
  				page_return(player, target, "Idle", A_IDLE, NULL);
  
  				safe_str(tprintf("%d ", target), buf2, &bp2);
  				count++;
  			}
  		}
  	} else {
  		if(ismessage)
  			target = atoi(tname);
  		if(target == NOTHING) {
  			notify_printf(player, "I don't recognize \"%s\".", tname);
  		} else if(!page_check(player, target)) {
  			;
  		} else {
  
  			switch (*message) {
  			case ':':
  				notify_with_cause(target, player,
  								  tprintf("From afar,%s %s %s", aladd,
  										  Name(player), message + 1));
  				break;
  			case ';':
  				message++;
  				notify_with_cause(target, player,
  								  tprintf("From afar,%s %s%s", aladd,
  										  Name(player), message));
  				break;
  			case '"':
  				message++;
  			default:
  				notify_with_cause(target, player, tprintf("%s%s pages: %s",
  														  Name(player), aladd,
  														  message));
  
  			}
  			page_return(player, target, "Idle", A_IDLE, NULL);
  
  			safe_str(tprintf("%d ", target), buf2, &bp2);
  			safe_str(tprintf("%s, ", Name(target)), buf1, &bp);
  			count++;
  		}
  		*(bp - 2) = '\0';
  	}
  
  	if(count == 0) {
  		free_lbuf(buf1);
  		free_lbuf(buf2);
  		return;
  	}
  	*(bp2 - 1) = '\0';
  	atr_add(player, A_LASTPAGE, buf2, Owner(player), aflags);
  
  	if(count == 1) {
  		if(*buf1) {
  			if(ispose != 1) {
  				notify_printf(player, "You paged %s with '%s'.", buf1, mp);
  			} else {
  				if(mp[0] == ':')
  					notify_printf(player, "Long distance to %s: %s %s",
  								  buf1, Name(player), mp + 1);
  				else
  					notify_printf(player, "Long distance to %s: %s%s",
  								  buf1, Name(player), mp + 1);
  			}
  		}
  	} else {
  		*(bp - 2) = ')';
  		*(bp - 1) = '\0';
  
  		if(*buf1) {
  			if(ispose != 1) {
  				notify_printf(player, "You paged (%s with '%s'.", buf1, mp);
  			} else {
  				if(mp[0] == ':')
  					notify_printf(player, "Long distance to (%s: %s %s",
  								  buf1, Name(player), mp + 1);
  				else
  					notify_printf(player, "Long distance to (%s: %s%s",
  								  buf1, Name(player), mp + 1);
  			}
  		}
  	}
  
  	free_lbuf(buf1);
  	free_lbuf(buf2);
  }
  
  /**
   * Messages to specific players, or to all but specific players.
   */
  void whisper_pose(dbref player, dbref target, char *message)
  {
  	char *buff;
  
  	buff = alloc_lbuf("do_pemit.whisper.pose");
  	StringCopy(buff, Name(player));
  	notify_printf(player, "%s senses \"%s%s\"", Name(target), buff, message);
  	notify_with_cause(target, player, tprintf("You sense %s%s", buff,
  											  message));
  	free_lbuf(buff);
  }
  
  void do_pemit_list(dbref player, char *list, const char *message)
  {
  	/*
  	 * Send a message to a list of dbrefs. To avoid repeated generation * 
  	 * of the NOSPOOF string, we set it up the first time we
  	 * encounter something Nospoof, and then check for it
  	 * thereafter. The list is destructively modified. 
  	 */
  
  	char *p;
  	dbref who;
  	int ok_to_do;
  
  	if(!message || !*message || !list || !*list)
  		return;
  
  	for(p = (char *) strtok(list, " "); p != NULL;
  		p = (char *) strtok(NULL, " ")) {
  
  		ok_to_do = 0;
  		init_match(player, p, TYPE_PLAYER);
  		match_everything(0);
  		who = match_result();
  
  		if(!ok_to_do && (Long_Fingers(player) || nearby(player, who) ||
  						 Controls(player, who))) {
  			ok_to_do = 1;
  		}
  		if(!ok_to_do && (isPlayer(who))
  		   && mudconf.pemit_players) {
  			if(!page_check(player, who))
  				return;
  			ok_to_do = 1;
  		}
  		switch (who) {
  		case NOTHING:
  			notify(player, "Emit to whom?");
  			break;
  		case AMBIGUOUS:
  			notify(player, "I don't know who you mean!");
  			break;
  		default:
  			if(!ok_to_do) {
  				notify(player, "You cannot do that.");
  				break;
  			}
  			if(Good_obj(who))
  				notify_with_cause(who, player, message);
  		}
  	}
  }
  
  void do_pemit(dbref player, dbref cause, int key, char *recipient,
  			  char *message)
  {
  	dbref target, loc;
  	char *buf2, *bp;
  	int do_contents, ok_to_do, depth, pemit_flags;
  
  	if(key & PEMIT_LIST) {
  		do_pemit_list(player, recipient, message);
  		return;
  	}
  	if(key & PEMIT_CONTENTS) {
  		do_contents = 1;
  		key &= ~PEMIT_CONTENTS;
  	} else {
  		do_contents = 0;
  	}
  	pemit_flags = key & (PEMIT_HERE | PEMIT_ROOM );
  	key &= ~(PEMIT_HERE | PEMIT_ROOM );
  	ok_to_do = 0;
  
  	switch (key) {
  	case PEMIT_FSAY:
  	case PEMIT_FPOSE:
  	case PEMIT_FPOSE_NS:
  	case PEMIT_FEMIT:
  		target = match_controlled(player, recipient);
  		if(target == NOTHING)
  			return;
  		ok_to_do = 1;
  		break;
  	default:
  		init_match(player, recipient, TYPE_PLAYER);
  		match_everything(0);
  		target = match_result();
  	}
  
  	switch (target) {
  	case NOTHING:
  		switch (key) {
  		case PEMIT_WHISPER:
  			notify(player, "Whisper to whom?");
  			break;
  		case PEMIT_PEMIT:
  			notify(player, "Emit to whom?");
  			break;
  		case PEMIT_OEMIT:
  			notify(player, "Emit except to whom?");
  			break;
  		default:
  			notify(player, "Sorry.");
  		}
  		break;
  	case AMBIGUOUS:
  		notify(player, "I don't know who you mean!");
  		break;
  	default:
  		/*
  		 * Enforce locality constraints 
  		 */
  
  		if(!ok_to_do && (nearby(player, target) || Long_Fingers(player)
  						 || Controls(player, target))) {
  			ok_to_do = 1;
  		}
  		if(!ok_to_do && (key == PEMIT_PEMIT) &&
  		   (Typeof(target) == TYPE_PLAYER) && mudconf.pemit_players) {
  			if(!page_check(player, target))
  				return;
  			ok_to_do = 1;
  		}
  		if(!ok_to_do && (!mudconf.pemit_any || (key != PEMIT_PEMIT))) {
  			notify(player, "You are too far away to do that.");
  			return;
  		}
  		if(do_contents && !Controls(player, target) && !mudconf.pemit_any) {
  			notify(player, "Permission denied.");
  			return;
  		}
  		loc = where_is(target);
  
  		switch (key) {
  		case PEMIT_PEMIT:
  			if(do_contents) {
  				if(Has_contents(target)) {
  					notify_all_from_inside(target, player, message);
  				}
  			} else {
  				notify_with_cause(target, player, message);
  
  			}
  			break;
  		case PEMIT_OEMIT:
  			notify_except(Location(target), player, target, message);
  			break;
  		case PEMIT_WHISPER:
  			switch (*message) {
  			case ':':
  				message[0] = ' ';
  				whisper_pose(player, target, message);
  				break;
  			case ';':
  				message++;
  				whisper_pose(player, target, message);
  				break;
  			case '"':
  				message++;
  			default:
  				notify_printf(player, "You whisper \"%s\" to %s.",
  							  message, Name(target));
  				notify_with_cause(target, player,
  								  tprintf("%s whispers \"%s\"", Name(player),
  										  message));
  			}
  			if((!mudconf.quiet_whisper) && !Wizard(player)) {
  				loc = where_is(player);
  				if(loc != NOTHING) {
  					buf2 = alloc_lbuf("do_pemit.whisper.buzz");
  					bp = buf2;
  					safe_str(Name(player), buf2, &bp);
  					safe_str((char *) " whispers something to ", buf2, &bp);
  					safe_str(Name(target), buf2, &bp);
  					*bp = '\0';
  					notify_except2(loc, player, player, target, buf2);
  					free_lbuf(buf2);
  				}
  			}
  			break;
  		case PEMIT_FSAY:
  			notify_printf(target, "You say \"%s\"", message);
  			if(loc != NOTHING) {
  				notify_except(loc, player, target,
  							  tprintf("%s says \"%s\"", Name(target),
  									  message));
  			}
  			break;
  		case PEMIT_FPOSE:
  			notify_all_from_inside(loc, player, tprintf("%s %s",
  														Name(target),
  														message));
  			break;
  		case PEMIT_FPOSE_NS:
  			notify_all_from_inside(loc, player, tprintf("%s%s",
  														Name(target),
  														message));
  			break;
  		case PEMIT_FEMIT:
  			if((pemit_flags & PEMIT_HERE) || !pemit_flags)
  				notify_all_from_inside(loc, player, message);
  			if(pemit_flags & PEMIT_ROOM) {
  				if((Typeof(loc) == TYPE_ROOM) && (pemit_flags & PEMIT_HERE)) {
  					return;
  				}
  				depth = 0;
  				while ((Typeof(loc) != TYPE_ROOM) && (depth++ < 20)) {
  					loc = Location(loc);
  					if((loc == NOTHING) || (loc == Location(loc)))
  						return;
  				}
  				if(Typeof(loc) == TYPE_ROOM) {
  					notify_all_from_inside(loc, player, message);
  				}
  			}
  			break;
  
  		}
  	}
  }
  