--- /dev/null	2015-05-20 11:04:07.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/common/doname.cc	2015-05-20 11:04:07.855148235 -0400
@@ -0,0 +1,3786 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)doname.cc 1.115 06/12/12
+ */
+
+#pragma	ident	"@(#)doname.cc	1.115	06/12/12"
+
+/*
+ *	doname.c
+ *
+ *	Figure out which targets are out of date and rebuild them
+ */
+
+/*
+ * Included files
+ */
+#include <avo/avo_alloca.h>		/* alloca() */
+#if defined(TEAMWARE_MAKE_CMN)
+#include <avo/util.h>		/* avo_get_user(), avo_hostname() */
+#endif
+
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+#	include <avo/strings.h>	/* AVO_STRDUP() */
+#	include <dm/Avo_MToolJobResultMsg.h>
+#	include <dm/Avo_MToolJobStartMsg.h>
+#	include <dm/Avo_MToolRsrcInfoMsg.h>
+#	include <dm/Avo_macro_defs.h> /* AVO_BLOCK_INTERUPTS & AVO_UNBLOCK_INTERUPTS */
+#	include <dmthread/Avo_ServerState.h>
+#	include <rw/pstream.h>
+#	include <rw/xdrstrea.h>
+#endif
+
+#include <fcntl.h>
+#include <mk/defs.h>
+#include <mksh/i18n.h>		/* get_char_semantics_value() */
+#include <mksh/macro.h>		/* getvar(), expand_value() */
+#include <mksh/misc.h>		/* getmem() */
+#include <poll.h>
+
+#ifdef PARALLEL
+#	include <rx/api.h>
+#endif
+
+#include <signal.h>
+
+#ifndef HP_UX
+#	include <stropts.h>
+#endif
+
+#include <sys/errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/utsname.h>	/* uname() */
+#include <sys/wait.h>
+#include <unistd.h>		/* close() */
+
+/*
+ * Defined macros
+ */
+#ifndef PARALLEL
+#	define LOCALHOST "localhost"
+#endif
+
+#define MAXRULES 100
+
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+#define SEND_MTOOL_MSG(cmds) \
+	if (send_mtool_msgs) { \
+		cmds \
+	}
+#else
+#define SEND_MTOOL_MSG(cmds) 
+#endif
+
+// Sleep for .1 seconds between stat()'s
+const int	STAT_RETRY_SLEEP_TIME = 100000;
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+static char	hostName[MAXNAMELEN] = "";
+static char	userName[MAXNAMELEN] = "";
+
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+	static FILE	*mtool_msgs_fp;
+	static XDR 	xdrs;
+	static int	sent_rsrc_info_msg = 0;
+#endif
+
+static int	second_pass = 0;
+
+/*
+ * File table of contents
+ */
+extern	Doname		doname_check(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic);
+extern	Doname		doname(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic);
+static	Boolean		check_dependencies(Doname *result, Property line, Boolean do_get, Name target, Name true_target, Boolean doing_subtree, Chain *out_of_date_tail, Property old_locals, Boolean implicit, Property *command, Name less, Boolean rechecking_target, Boolean recheck_conditionals);
+void		dynamic_dependencies(Name target);
+static	Doname		run_command(register Property line, Boolean print_machine);
+extern	Doname		execute_serial(Property line);
+extern	Name		vpath_translation(register Name cmd);
+extern	void		check_state(Name temp_file_name);
+static	void		read_dependency_file(register Name filename);
+static	void		check_read_state_file(void);
+static	void		do_assign(register Name line, register Name target);
+static	void		build_command_strings(Name target, register Property line);
+static	Doname		touch_command(register Property line, register Name target, Doname result);
+extern	void		update_target(Property line, Doname result);
+static	Doname		sccs_get(register Name target, register Property *command);
+extern	void		read_directory_of_file(register Name file);
+static	void		add_pattern_conditionals(register Name target);
+extern	void		set_locals(register Name target, register Property old_locals);
+extern	void		reset_locals(register Name target, register Property old_locals, register Property conditional, register int index);
+extern	Boolean		check_auto_dependencies(Name target, int auto_count, Name *automatics);
+static	void		delete_query_chain(Chain ch);
+
+// From read2.cc
+extern	Name		normalize_name(register wchar_t *name_string, register int length);
+
+
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+	static void		append_job_result_msg(Avo_MToolJobResultMsg *job_result_msg);
+	static int		pollResults(char *outFn, char *errFn, char *hostNm);
+	static void		pollResultsAction(char *outFn, char *errFn);
+	static void		rxmGetNextResultsBlock(int fd);
+	static int		us_sleep(unsigned int nusecs);
+	extern "C" void		Avo_PollResultsAction_Sigusr1Handler(int foo);
+#endif
+
+/*
+ * DONE.
+ *
+ *	doname_check(target, do_get, implicit, automatic)
+ *
+ *	Will call doname() and then inspect the return value
+ *
+ *	Return value:
+ *				Indication if the build failed or not
+ *
+ *	Parameters:
+ *		target		The target to build
+ *		do_get		Passed thru to doname()
+ *		implicit	Passed thru to doname()
+ *		automatic	Are we building a hidden dependency?
+ *
+ *	Global variables used:
+ *		build_failed_seen	Set if -k is on and error occurs
+ *		continue_after_error	Indicates that -k is on
+ *		report_dependencies	No error msg if -P is on
+ */
+Doname
+doname_check(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic)
+{
+	int first_time = 1;
+	(void) fflush(stdout);
+try_again:
+	switch (doname(target, do_get, implicit, automatic)) {
+	case build_ok:
+		second_pass = 0;
+		return build_ok;
+	case build_running:
+		second_pass = 0;
+		return build_running;
+	case build_failed:
+		if (!continue_after_error) {
+			fatal(catgets(catd, 1, 13, "Target `%s' not remade because of errors"),
+			      target->string_mb);
+		}
+		build_failed_seen = true;
+		second_pass = 0;
+		return build_failed;
+	case build_dont_know:
+		/*
+		 * If we can't figure out how to build an automatic
+		 * (hidden) dependency, we just ignore it.
+		 * We later declare the target to be out of date just in
+		 * case something changed.
+		 * Also, don't complain if just reporting the dependencies
+		 * and not building anything.
+		 */
+		if (automatic || (report_dependencies_level > 0)) {
+			second_pass = 0;
+			return build_dont_know;
+		}
+		if(first_time) {
+			first_time = 0;
+			second_pass = 1;
+			goto try_again;
+		}
+		second_pass = 0;
+		if (continue_after_error && !svr4) {
+			warning(catgets(catd, 1, 14, "Don't know how to make target `%s'"),
+				target->string_mb);
+			build_failed_seen = true;
+			return build_failed;
+		}
+		fatal(catgets(catd, 1, 15, "Don't know how to make target `%s'"), target->string_mb);
+		break;
+	}
+#ifdef lint
+	return build_failed;
+#endif
+}
+
+
+void
+enter_explicit_rule_from_dynamic_rule(Name target, Name source)
+{
+	Property line, source_line;
+	Dependency dependency;
+
+	source_line = get_prop(source->prop, line_prop);
+	line = maybe_append_prop(target, line_prop);
+	line->body.line.sccs_command = false;
+	line->body.line.target = target;
+	if (line->body.line.command_template == NULL) {
+		line->body.line.command_template = source_line->body.line.command_template;
+		for (dependency = source_line->body.line.dependencies;
+		     dependency != NULL;
+		     dependency = dependency->next) {
+			enter_dependency(line, dependency->name, false);
+		}
+		line->body.line.less = target;
+	}
+	line->body.line.percent = NULL;
+}
+
+
+
+Name
+find_dyntarget(Name target)
+{
+	Dyntarget		p;
+	int			i;
+	String_rec		string;
+	wchar_t			buffer[STRING_BUFFER_LENGTH];
+	wchar_t			*pp, * bufend;
+	wchar_t			tbuffer[MAXPATHLEN];
+	Wstring			wcb(target);
+
+	for (p = dyntarget_list; p != NULL; p = p->next) {
+		INIT_STRING_FROM_STACK(string, buffer);
+		expand_value(p->name, &string, false);
+		i = 0;
+		pp = string.buffer.start;
+		bufend = pp + STRING_BUFFER_LENGTH;
+		while((*pp != nul_char) && (pp < bufend)) {
+			if(iswspace(*pp)) {
+				tbuffer[i] = nul_char;
+				if(i > 0) {
+					if (wcb.equal(tbuffer)) {
+						enter_explicit_rule_from_dynamic_rule(target, p->name);
+						return(target);
+					}
+				}
+				pp++;
+				i = 0;
+				continue;
+			}
+			tbuffer[i] = *pp;
+			i++;
+			pp++;
+			if(*pp == nul_char) {
+				tbuffer[i] = nul_char;
+				if(i > 0) {
+					if (wcb.equal(tbuffer)) {
+						enter_explicit_rule_from_dynamic_rule(target, p->name);
+						return(target);
+					}
+				}
+				break;
+			}
+		}
+	}
+	return(NULL);
+}
+
+/*
+ * DONE.
+ *
+ *	doname(target, do_get, implicit)
+ *
+ *	Chases all files the target depends on and builds any that
+ *	are out of date. If the target is out of date it is then rebuilt.
+ *
+ *	Return value:
+ *				Indiates if build failed or nt
+ *
+ *	Parameters:
+ *		target		Target to build
+ *		do_get		Run sccs get is nessecary
+ *		implicit	doname is trying to find an implicit rule
+ *
+ *	Global variables used:
+ *		assign_done	True if command line assgnment has happened
+ *		commands_done	Preserved for the case that we need local value
+ *		debug_level	Should we trace make's actions?
+ *		default_rule	The rule for ".DEFAULT", used as last resort
+ *		empty_name	The Name "", used when looking for single sfx
+ *		keep_state	Indicates that .KEEP_STATE is on
+ *		parallel	True if building in parallel
+ *		recursion_level	Used for tracing
+ *		report_dependencies make -P is on
+ */
+Doname
+doname(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic)
+{
+	Doname			result = build_dont_know;
+	Chain			out_of_date_list = NULL;
+#ifdef TEAMWARE_MAKE_CMN
+	Chain			target_group;
+#endif
+	Property		old_locals = NULL;
+	register Property	line;
+	Property		command = NULL;
+	register Dependency	dependency;
+	Name			less = NULL;
+	Name			true_target = target;
+	Name			*automatics = NULL;
+	register int		auto_count;
+	Boolean			rechecking_target = false;
+	Boolean			saved_commands_done;
+	Boolean			restart = false;
+	Boolean			save_parallel = parallel;
+#ifdef NSE
+	Boolean			save_readdep;
+#endif
+	Boolean			doing_subtree = false;
+
+	Boolean			recheck_conditionals = false;
+
+	if (target->state == build_running) {
+		return build_running;
+	}
+	line = get_prop(target->prop, line_prop);
+#ifdef TEAMWARE_MAKE_CMN
+	if (line != NULL) {
+		/*
+		 * If this target is a member of target group and one of the
+		 * other members of the group is running, mark this target
+		 * as running.
+		 */
+		for (target_group = line->body.line.target_group;
+		     target_group != NULL;
+		     target_group = target_group->next) {
+			if (is_running(target_group->name)) {
+				target->state = build_running;
+				add_pending(target,
+					    recursion_level,
+					    do_get,
+					    implicit,
+					    false);
+				return build_running;
+			}
+		}
+	}
+#ifdef NSE
+        nse_check_file_backquotes(target->string);
+#endif
+#endif
+	/*
+	 * If the target is a constructed one for a "::" target,
+	 * we need to consider that.
+	 */
+	if (target->has_target_prop) {
+		true_target = get_prop(target->prop,
+				       target_prop)->body.target.target;
+		if (true_target->colon_splits > 0) {
+			/* Make sure we have a valid time for :: targets */
+			Property        time;
+
+			time = get_prop(true_target->prop, time_prop);
+			if (time != NULL) {
+				true_target->stat.time = time->body.time.time;
+			}
+		}
+	}
+	(void) exists(true_target);
+	/*
+	 * If the target has been processed, we don't need to do it again,
+	 * unless it depends on conditional macros or a delayed assignment,
+	 * or it has been done when KEEP_STATE is on.
+	 */
+	if (target->state == build_ok) {
+		if((!keep_state || (!target->depends_on_conditional && !assign_done))) {
+			return build_ok;
+		} else {
+			recheck_conditionals = true;
+		}
+  	}
+	if (target->state == build_subtree) {
+		/* A dynamic macro subtree is being built */
+		target->state = build_dont_know;
+		doing_subtree = true;
+		if (!target->checking_subtree) {
+			/*
+			 * This target has been started before and therefore
+			 * not all dependencies have to be built.
+			 */
+			restart = true;
+		}
+	} else if (target->state == build_pending) {
+		target->state = build_dont_know;
+		restart = true;
+/*
+#ifdef TEAMWARE_MAKE_CMN
+	} else if (parallel &&
+		   keep_state &&
+		   (target->conditional_cnt > 0)) {
+	    if (!parallel_ok(target, false)) {
+		add_subtree(target, recursion_level, do_get, implicit);
+		target->state = build_running;
+		return build_running;
+	    }
+#endif
+ */
+	}
+	/*
+	 * If KEEP_STATE is on, we have to rebuild the target if the
+	 * building of it caused new automatic dependencies to be reported.
+	 * This is where we restart the build.
+	 */
+	if (line != NULL) {
+		line->body.line.percent = NULL;
+	}
+recheck_target:
+	/* Init all local variables */
+	result = build_dont_know;
+	out_of_date_list = NULL;
+	command = NULL;
+	less = NULL;
+	auto_count = 0;
+	if (!restart && line != NULL) {
+		/*
+		 * If this target has never been built before, mark all
+		 * of the dependencies as never built.
+		 */
+		for (dependency = line->body.line.dependencies;
+		     dependency != NULL;
+		     dependency = dependency->next) {
+			dependency->built = false;
+		}
+	}
+	/* Save the set of automatic depes defined for this target */
+	if (keep_state &&
+	    (line != NULL) &&
+	    (line->body.line.dependencies != NULL)) {
+		Name *p;
+
+		/*
+		 * First run thru the dependency list to see how many
+		 * autos there are.
+		 */
+		for (dependency = line->body.line.dependencies;
+		     dependency != NULL;
+		     dependency = dependency->next) {
+			if (dependency->automatic && !dependency->stale) {
+				auto_count++;
+			}
+		}
+		/* Create vector to hold the current autos */
+		automatics =
+		  (Name *) alloca((int) (auto_count * sizeof (Name)));
+		/* Copy them */
+		for (p = automatics, dependency = line->body.line.dependencies;
+		     dependency != NULL;
+		     dependency = dependency->next) {
+			if (dependency->automatic && !dependency->stale) {
+				*p++ = dependency->name;
+			}
+		}
+	}
+	if (debug_level > 1) {
+		(void) printf(NOCATGETS("%*sdoname(%s)\n"),
+			      recursion_level,
+			      "",
+			      target->string_mb);
+	}
+	recursion_level++;
+	/* Avoid infinite loops */
+	if (target->state == build_in_progress) {
+		warning(catgets(catd, 1, 16, "Infinite loop: Target `%s' depends on itself"),
+			target->string_mb);
+		return build_ok;
+	}
+	target->state = build_in_progress;
+
+	/* Activate conditional macros for the target */
+	if (!target->added_pattern_conditionals) {
+		add_pattern_conditionals(target);
+		target->added_pattern_conditionals = true;
+	}
+	if (target->conditional_cnt > 0) {
+		old_locals = (Property) alloca(target->conditional_cnt *
+					       sizeof (Property_rec));
+		set_locals(target, old_locals);
+	}
+
+/*
+ * after making the call to dynamic_dependecies unconditional we can handle
+ * target names that are same as file name. In this case $$@ in the 
+ * dependencies did not mean anything. WIth this change it expands it
+ * as expected.
+ */
+	if (!target->has_depe_list_expanded)
+	{
+#ifdef NSE
+		save_readdep = reading_dependencies;
+		reading_dependencies= true;
+#endif
+		dynamic_dependencies(target);
+#ifdef NSE
+		reading_dependencies= save_readdep;
+#endif
+	}
+
+/*
+ *	FIRST SECTION -- GO THROUGH DEPENDENCIES AND COLLECT EXPLICIT
+ *	COMMANDS TO RUN
+ */
+	if ((line = get_prop(target->prop, line_prop)) != NULL) {
+		if (check_dependencies(&result,
+				       line,
+				       do_get,
+				       target,
+				       true_target,
+				       doing_subtree,
+				       &out_of_date_list,
+				       old_locals,
+				       implicit,
+				       &command,
+				       less,
+				       rechecking_target,
+				       recheck_conditionals)) {
+			return build_running;
+		}
+		if (line->body.line.query != NULL) {
+			delete_query_chain(line->body.line.query);
+		}
+		line->body.line.query = out_of_date_list;
+	}
+
+#ifdef PARALLEL
+	if (doing_subtree) {
+		parallel = false;
+	}
+#endif
+
+/*
+ * If the target is a :: type, do not try to find the rule for the target,
+ * all actions will be taken by separate branches.
+ * Else, we try to find an implicit rule using various methods,
+ * we quit as soon as one is found.
+ *
+ * [tolik, 12 Sep 2002] Do not try to find implicit rule for the target
+ * being rechecked - the target is being rechecked means that it already
+ * has explicit dependencies derived from an implicit rule found
+ * in previous step.
+ */
+	if (target->colon_splits == 0 && !rechecking_target) {
+		/* Look for percent matched rule */
+		if ((result == build_dont_know) &&
+		    (command == NULL)) {
+			switch (find_percent_rule(
+					target,
+					&command,
+					recheck_conditionals)) {
+			case build_failed:
+				result = build_failed;
+				break;
+#ifdef TEAMWARE_MAKE_CMN
+			case build_running:
+				target->state = build_running;
+				add_pending(target,
+					    --recursion_level,
+					    do_get,
+					    implicit,
+					    false);
+				if (target->conditional_cnt > 0) {
+					reset_locals(target,
+						     old_locals,
+						     get_prop(target->prop,
+							     conditional_prop),
+						     0);
+				}
+				return build_running;
+#endif
+			case build_ok:
+				result = build_ok;
+				break;
+			}
+		}
+		/* Look for double suffix rule */
+		if (result == build_dont_know) {
+			Property member;
+
+			if (target->is_member &&
+			    ((member = get_prop(target->prop, member_prop)) !=
+			     NULL)) {
+			        switch (find_ar_suffix_rule(target,
+						member->body.
+						member.member,
+						&command,
+						recheck_conditionals)) {
+				case build_failed:
+					result = build_failed;
+					break;
+#ifdef TEAMWARE_MAKE_CMN
+				case build_running:
+					target->state = build_running;
+					add_pending(target,
+						    --recursion_level,
+						    do_get,
+						    implicit,
+						    false);
+				    if (target->conditional_cnt > 0) {
+					    reset_locals(target,
+							 old_locals,
+							 get_prop(target->prop,
+							     conditional_prop),
+							 0);
+				    }
+					return build_running;
+#endif
+				default:
+					/* ALWAYS bind $% for old style */
+					/* ar rules */
+					if (line == NULL) {
+						line =
+						  maybe_append_prop(target,
+								    line_prop);
+					}
+					line->body.line.percent =
+					  member->body.member.member;
+					break;
+				}
+			} else {
+				switch (find_double_suffix_rule(target,
+						&command,
+						recheck_conditionals)) {
+				case build_failed:
+					result = build_failed;
+					break;
+#ifdef TEAMWARE_MAKE_CMN
+				case build_running:
+					target->state = build_running;
+					add_pending(target,
+						    --recursion_level,
+						    do_get,
+						    implicit,
+						    false);
+					if (target->conditional_cnt > 0) {
+						reset_locals(target,
+							     old_locals,
+							     get_prop(target->
+								      prop,
+								      conditional_prop),
+							     0);
+					}
+					return build_running;
+#endif
+				}
+			}
+		}
+		/* Look for single suffix rule */
+
+/* /tolik/
+ * I commented !implicit to fix bug 1247448: Suffix Rules failed when combine with Pattern Matching Rules.
+ * This caused problem with SVR4 tilde rules (infinite recursion). So I made some changes in "implicit.cc"
+ */
+/* /tolik, 06.21.96/
+ * Regression! See BugId 1255360
+ * If more than one percent rules are defined for the same target then
+ * the behaviour of 'make' with my previous fix may be different from one
+ * of the 'old make'. 
+ * The global variable second_pass (maybe it should be an argument to doname())
+ * is intended to avoid this regression. It is set in doname_check().
+ * First, 'make' will work as it worked before. Only when it is
+ * going to say "don't know how to make target" it sets second_pass to true and
+ * run 'doname' again but now trying to use Single Suffix Rules.
+ */
+		if ((result == build_dont_know) && !automatic && (!implicit || second_pass) &&
+		    ((line == NULL) ||
+		     ((line->body.line.target != NULL) &&
+		      !line->body.line.target->has_regular_dependency))) {
+			switch (find_suffix_rule(target,
+						 target,
+						 empty_name,
+						 &command,
+						 recheck_conditionals)) {
+			case build_failed:
+				result = build_failed;
+				break;
+#ifdef TEAMWARE_MAKE_CMN
+			case build_running:
+				target->state = build_running;
+				add_pending(target,
+					    --recursion_level,
+					    do_get,
+					    implicit,
+					    false);
+				if (target->conditional_cnt > 0) {
+					reset_locals(target,
+						     old_locals,
+						     get_prop(target->prop,
+							     conditional_prop),
+						     0);
+				}
+				return build_running;
+#endif
+			}
+		}
+		/* Try to sccs get */
+		if ((command == NULL) &&
+		    (result == build_dont_know) &&
+		    do_get) {
+			result = sccs_get(target, &command);
+		}
+
+		/* Use .DEFAULT rule if it is defined. */
+		if ((command == NULL) &&
+		    (result == build_dont_know) &&
+		    (true_target->colons == no_colon) &&
+		    default_rule &&
+		    !implicit) {
+			/* Make sure we have a line prop */
+			line = maybe_append_prop(target, line_prop);
+			command = line;
+			Boolean out_of_date;
+			if (true_target->is_member) {
+				out_of_date = (Boolean) OUT_OF_DATE_SEC(true_target->stat.time,
+									line->body.line.dependency_time);
+			} else {
+				out_of_date = (Boolean) OUT_OF_DATE(true_target->stat.time,
+								    line->body.line.dependency_time);
+			}
+			if (build_unconditional || out_of_date) {
+				line->body.line.is_out_of_date = true;
+				if (debug_level > 0) {
+					(void) printf(catgets(catd, 1, 17, "%*sBuilding %s using .DEFAULT because it is out of date\n"),
+						      recursion_level,
+						      "",
+						      true_target->string_mb);
+				}
+			}
+			line->body.line.sccs_command = false;
+			line->body.line.command_template = default_rule;
+			line->body.line.target = true_target;
+			line->body.line.star = NULL;
+			line->body.line.less = true_target;
+			line->body.line.percent = NULL;
+		}
+	}
+
+	/* We say "target up to date" if no cmd were executed for the target */
+	if (!target->is_double_colon_parent) {
+		commands_done = false;
+	}
+
+	silent = silent_all;
+	ignore_errors = ignore_errors_all;
+	if  (posix)
+	{
+	  if  (!silent)
+	  {
+            silent = (Boolean) target->silent_mode;
+	  }
+	  if  (!ignore_errors)
+	  {
+            ignore_errors = (Boolean) target->ignore_error_mode;
+	  }
+	}
+
+	int doname_dyntarget = 0;
+r_command:
+	/* Run commands if any. */
+	if ((command != NULL) &&
+	    (command->body.line.command_template != NULL)) {
+		if (result != build_failed) {
+			result = run_command(command, 
+					     (Boolean) ((parallel || save_parallel) && !silent));
+#ifdef NSE
+			nse_check_no_deps_no_rule(target,
+				get_prop(target->prop, line_prop), command);
+#endif
+		}
+		switch (result) {
+#ifdef TEAMWARE_MAKE_CMN
+		case build_running:
+			add_running(target,
+				    true_target,
+				    command,
+				    --recursion_level,
+				    auto_count,
+				    automatics,
+				    do_get,
+				    implicit);
+			target->state = build_running;
+			if ((line = get_prop(target->prop,
+					     line_prop)) != NULL) {
+				if (line->body.line.query != NULL) {
+					delete_query_chain(line->body.line.query);
+				}
+				line->body.line.query = NULL;
+			}
+			if (target->conditional_cnt > 0) {
+				reset_locals(target,
+					     old_locals,
+					     get_prop(target->prop,
+						     conditional_prop),
+					     0);
+			}
+			return build_running;
+		case build_serial:
+			add_serial(target,
+				   --recursion_level,
+				   do_get,
+				   implicit);
+			target->state = build_running;
+			line = get_prop(target->prop, line_prop);
+			if (line != NULL) {
+				if (line->body.line.query != NULL) {
+					delete_query_chain(line->body.line.query);
+				}
+				line->body.line.query = NULL;
+			}
+			if (target->conditional_cnt > 0) {
+				reset_locals(target,
+					     old_locals,
+					     get_prop(target->prop,
+						     conditional_prop),
+					     0);
+			}
+			return build_running;
+#endif
+		case build_ok:
+			/* If all went OK set a nice timestamp */
+			if (true_target->stat.time == file_doesnt_exist) {
+				true_target->stat.time = file_max_time;
+			}
+			break;
+		}
+	} else {
+		/*
+		 * If no command was found for the target, and it doesn't
+		 * exist, and it is mentioned as a target in the makefile,
+		 * we say it is extremely new and that it is OK.
+		 */
+		if (target->colons != no_colon) {
+			if (true_target->stat.time == file_doesnt_exist){
+				true_target->stat.time = file_max_time;
+			}
+			result = build_ok;
+		}
+		/*
+		 * Trying dynamic targets.
+		 */
+		if(!doname_dyntarget) {
+			doname_dyntarget = 1;
+			Name dtarg = find_dyntarget(target);
+			if(dtarg!=NULL) {
+				if (!target->has_depe_list_expanded) {
+					dynamic_dependencies(target);
+				}
+				if ((line = get_prop(target->prop, line_prop)) != NULL) {
+					if (check_dependencies(&result,
+					                       line,
+					                       do_get,
+					                       target,
+					                       true_target,
+					                       doing_subtree,
+					                       &out_of_date_list,
+					                       old_locals,
+					                       implicit,
+					                       &command,
+					                       less,
+					                       rechecking_target,
+					                       recheck_conditionals))
+					{
+						return build_running;
+					}
+					if (line->body.line.query != NULL) {
+						delete_query_chain(line->body.line.query);
+					}
+					line->body.line.query = out_of_date_list;
+				}
+				goto r_command;
+			}
+		}
+		/*
+		 * If the file exists, it is OK that we couldnt figure
+		 * out how to build it.
+		 */
+		(void) exists(target);
+		if ((target->stat.time != file_doesnt_exist) &&
+		    (result == build_dont_know)) {
+			result = build_ok;
+		}
+	}
+
+	/*
+	 * Some of the following is duplicated in the function finish_doname.
+	 * If anything is changed here, check to see if it needs to be
+	 * changed there.
+	 */
+	if ((line = get_prop(target->prop, line_prop)) != NULL) {
+		if (line->body.line.query != NULL) {
+			delete_query_chain(line->body.line.query);
+		}
+		line->body.line.query = NULL;
+	}
+	target->state = result;
+	parallel = save_parallel;
+	if (target->conditional_cnt > 0) {
+		reset_locals(target,
+			     old_locals,
+			     get_prop(target->prop, conditional_prop),
+			     0);
+	}
+	recursion_level--;
+	if (target->is_member) {
+		Property member;
+
+		/* Propagate the timestamp from the member file to the member*/
+		if ((target->stat.time != file_max_time) &&
+		    ((member = get_prop(target->prop, member_prop)) != NULL) &&
+		    (exists(member->body.member.member) > file_doesnt_exist)) {
+			target->stat.time =
+			  member->body.member.member->stat.time;
+		}
+	}
+	/*
+	 * Check if we found any new auto dependencies when we
+	 * built the target.
+	 */
+	if ((result == build_ok) && check_auto_dependencies(target,
+							    auto_count,
+							    automatics)) {
+		if (debug_level > 0) {
+			(void) printf(catgets(catd, 1, 18, "%*sTarget `%s' acquired new dependencies from build, rechecking all dependencies\n"),
+				      recursion_level,
+				      "",
+				      true_target->string_mb);
+		}
+		rechecking_target = true;
+		saved_commands_done = commands_done;
+		goto recheck_target;
+	}
+
+	if (rechecking_target && !commands_done) {
+		commands_done = saved_commands_done;
+	}
+
+	return result;
+}
+
+/*
+ * DONE.
+ *
+ *	check_dependencies(result, line, do_get,
+ *			target, true_target, doing_subtree, out_of_date_tail,
+ *			old_locals, implicit, command, less, rechecking_target)
+ *
+ *	Return value:
+ *				True returned if some dependencies left running
+ *				
+ *	Parameters:
+ *		result		Pointer to cell we update if build failed
+ *		line		We get the dependencies from here
+ *		do_get		Allow use of sccs get in recursive doname()
+ *		target		The target to chase dependencies for
+ *		true_target	The real one for :: and lib(member)
+ *		doing_subtree	True if building a conditional macro subtree
+ *		out_of_date_tail Used to set the $? list
+ *		old_locals	Used for resetting the local macros
+ *		implicit	Called when scanning for implicit rules?
+ *		command		Place to stuff command
+ *		less		Set to $< value
+ *
+ *	Global variables used:
+ *		command_changed	Set if we suspect .make.state needs rewrite
+ *		debug_level	Should we trace actions?
+ *		force		The Name " FORCE", compared against
+ *		recursion_level	Used for tracing
+ *		rewrite_statefile Set if .make.state needs rewriting
+ *		wait_name	The Name ".WAIT", compared against
+ */
+static Boolean
+#ifdef TEAMWARE_MAKE_CMN
+check_dependencies(Doname *result, Property line, Boolean do_get, Name target, Name true_target, Boolean doing_subtree, Chain *out_of_date_tail, Property old_locals, Boolean implicit, Property *command, Name less, Boolean rechecking_target, Boolean recheck_conditionals)
+#else
+check_dependencies(Doname *result, Property line, Boolean do_get, Name target, Name true_target, Boolean, Chain *out_of_date_tail, Property, Boolean, Property *command, Name less, Boolean rechecking_target, Boolean recheck_conditionals)
+#endif
+{
+	Boolean			dependencies_running;
+	register Dependency	dependency;
+	Doname			dep_result;
+	Boolean			dependency_changed = false;
+
+	line->body.line.dependency_time = file_doesnt_exist;
+	if (line->body.line.query != NULL) {
+		delete_query_chain(line->body.line.query);
+	}
+	line->body.line.query = NULL;
+	line->body.line.is_out_of_date = false;
+	dependencies_running = false;
+	/*
+	 * Run thru all the dependencies and call doname() recursively
+	 * on each of them.
+	 */
+	for (dependency = line->body.line.dependencies;
+	     dependency != NULL;
+	     dependency = dependency->next) {
+		Boolean this_dependency_changed = false;
+
+		if (!dependency->automatic &&
+		    (rechecking_target || target->rechecking_target)) {
+			/*
+			 * We only bother with the autos when rechecking
+			 */
+			continue;
+		}
+
+		if (dependency->name == wait_name) {
+			/*
+			 * The special target .WAIT means finish all of
+			 * the prior dependencies before continuing.
+			 */
+			if (dependencies_running) {
+				break;
+			}
+#ifdef DISTRIBUTED
+		} else if ((!parallel_ok(dependency->name, false)) &&
+			   (dependencies_running)) {
+			/*
+			 * If we can't execute the current dependency in
+			 * parallel, hold off the dependency processing
+			 * to preserve the order of the dependencies.
+			 */
+			break;
+#endif
+		} else {
+			timestruc_t	depe_time = file_doesnt_exist;
+
+
+			if (true_target->is_member) {
+				depe_time = exists(dependency->name);
+			}
+			if (dependency->built ||
+			    (dependency->name->state == build_failed)) {
+				dep_result = (Doname) dependency->name->state;
+			} else {
+#ifdef NSE
+				nse_check_sccs(target->string,
+					       dependency->name->string);
+                                nse_check_derived_src(target,
+	                                       dependency->name->string,
+	                                       line->body.line.command_template);
+#endif
+				dep_result = doname_check(dependency->name,
+							  do_get,
+							  false,
+							  (Boolean) dependency->automatic);
+			}
+			if (true_target->is_member || dependency->name->is_member) {
+				/* should compare only secs, cause lib members does not have nsec time resolution */
+				if (depe_time.tv_sec != dependency->name->stat.time.tv_sec) {
+					this_dependency_changed =
+					  dependency_changed =
+					    true;
+				}
+			} else {
+				if (depe_time != dependency->name->stat.time) {
+					this_dependency_changed =
+					  dependency_changed =
+					    true;
+				}
+			}
+			dependency->built = true;
+			switch (dep_result) {
+			case build_running:
+				dependencies_running = true;
+				continue;
+			case build_failed:
+				*result = build_failed;
+				break;
+			case build_dont_know:
+/*
+ * If make can't figure out how to make a dependency, maybe the dependency
+ * is out of date. In this case, we just declare the target out of date
+ * and go on. If we really need the dependency, the make'ing of the target
+ * will fail. This will only happen for automatic (hidden) dependencies.
+ */
+				if(!recheck_conditionals) {
+					line->body.line.is_out_of_date = true;
+				}
+				/*
+				 * Make sure the dependency is not saved
+				 * in the state file.
+				 */
+				dependency->stale = true;
+				rewrite_statefile =
+				  command_changed =
+				    true;
+				if (debug_level > 0) {
+					(void) printf(catgets(catd, 1, 19, "Target %s rebuilt because dependency %s does not exist\n"),
+						     true_target->string_mb,
+						     dependency->name->string_mb);
+				}
+				break;
+			}
+			if (dependency->name->depends_on_conditional) {
+				target->depends_on_conditional = true;
+			}
+			if (dependency->name == force) {
+				target->stat.time =
+				  dependency->name->stat.time;
+			}
+			/*
+			 * Propagate new timestamp from "member" to
+			 * "lib.a(member)".
+			 */
+			(void) exists(dependency->name);
+
+			/* Collect the timestamp of the youngest dependency */
+			line->body.line.dependency_time =
+			  MAX(dependency->name->stat.time,
+			      line->body.line.dependency_time);
+
+			/* Correction: do not consider nanosecs for members */
+			if(true_target->is_member || dependency->name->is_member) {
+				line->body.line.dependency_time.tv_nsec = 0;
+			}
+
+			if (debug_level > 1) {
+				(void) printf(catgets(catd, 1, 20, "%*sDate(%s)=%s \n"),
+					      recursion_level,
+					      "",
+					      dependency->name->string_mb,
+					      time_to_string(dependency->name->
+							     stat.time));
+				if (dependency->name->stat.time > line->body.line.dependency_time) {
+					(void) printf(catgets(catd, 1, 21, "%*sDate-dependencies(%s) set to %s\n"),
+						      recursion_level,
+						      "",
+						      true_target->string_mb,
+						      time_to_string(line->body.line.
+								     dependency_time));
+				}
+			}
+
+			/* Build the $? list */
+			if (true_target->is_member) {
+				if (this_dependency_changed == true) {
+					true_target->stat.time = dependency->name->stat.time;
+					true_target->stat.time.tv_sec--;
+				} else {
+					/* Dina: 
+					 * The next statement is commented
+					 * out as a fix for bug #1051032.
+					 * if dependency hasn't changed
+					 * then there's no need to invalidate
+					 * true_target. This statemnt causes
+					 * make to take much longer to process
+					 * an already-built archive. Soren
+					 * said it was a quick fix for some
+					 * problem he doesn't remember.
+					true_target->stat.time = file_no_time;
+					 */
+					(void) exists(true_target);
+				}
+			} else {
+				(void) exists(true_target);
+			}
+			Boolean out_of_date;
+			if (true_target->is_member || dependency->name->is_member) {
+				out_of_date = (Boolean) OUT_OF_DATE_SEC(true_target->stat.time,
+							                dependency->name->stat.time);
+			} else {
+				out_of_date = (Boolean) OUT_OF_DATE(true_target->stat.time,
+							            dependency->name->stat.time);
+			}
+			if ((build_unconditional || out_of_date) &&
+			    (dependency->name != force) &&
+			    (dependency->stale == false)) {
+				*out_of_date_tail = ALLOC(Chain);
+				if (dependency->name->is_member &&
+				    (get_prop(dependency->name->prop,
+					      member_prop) != NULL)) {
+					(*out_of_date_tail)->name =
+					  get_prop(dependency->name->prop,
+						   member_prop)->
+						     body.member.member;
+				} else {
+					(*out_of_date_tail)->name =
+					  dependency->name;
+				}
+				(*out_of_date_tail)->next = NULL;
+				out_of_date_tail = &(*out_of_date_tail)->next;
+				if (debug_level > 0) {
+					if (dependency->name->stat.time == file_max_time) {
+						(void) printf(catgets(catd, 1, 22, "%*sBuilding %s because %s does not exist\n"),
+							      recursion_level,
+							      "",
+							      true_target->string_mb,
+							      dependency->name->string_mb);
+					} else {
+						(void) printf(catgets(catd, 1, 23, "%*sBuilding %s because it is out of date relative to %s\n"),
+							      recursion_level,
+							      "",
+							      true_target->string_mb,
+							      dependency->name->string_mb);
+					}
+				}
+			}
+			if (dependency->name == force) {
+				force->stat.time =
+				  file_max_time;
+				force->state = build_dont_know;
+			}
+		}
+	}
+#ifdef TEAMWARE_MAKE_CMN
+	if (dependencies_running) {
+		if (doing_subtree) {
+			if (target->conditional_cnt > 0) {
+				reset_locals(target,
+					     old_locals,
+					     get_prop(target->prop,
+						      conditional_prop),
+					     0);
+			}
+			return true;
+		} else {
+			target->state = build_running;
+			add_pending(target,
+				    --recursion_level,
+				    do_get,
+				    implicit,
+				    false);
+			if (target->conditional_cnt > 0) {
+				reset_locals(target,
+					     old_locals,
+					     get_prop(target->prop,
+						      conditional_prop),
+					     0);
+			}
+			return true;
+		}
+	}
+#endif
+	/*
+	 * Collect the timestamp of the youngest double colon target
+	 * dependency.
+	 */
+	if (target->is_double_colon_parent) {
+		for (dependency = line->body.line.dependencies;
+		     dependency != NULL;
+		     dependency = dependency->next) {
+			Property        tmp_line;
+
+			if ((tmp_line = get_prop(dependency->name->prop, line_prop)) != NULL) {
+				if(tmp_line->body.line.dependency_time != file_max_time) {
+					target->stat.time =
+					  MAX(tmp_line->body.line.dependency_time,
+					      target->stat.time);
+				}
+			}
+		}
+	}
+	if ((true_target->is_member) && (dependency_changed == true)) {
+		true_target->stat.time = file_no_time;
+	}
+	/*
+	 * After scanning all the dependencies, we check the rule
+	 * if we found one.
+	 */
+	if (line->body.line.command_template != NULL) {
+		if (line->body.line.command_template_redefined) {
+			warning(catgets(catd, 1, 24, "Too many rules defined for target %s"),
+				target->string_mb);
+		}
+		*command = line;
+		/* Check if the target is out of date */
+		Boolean out_of_date;
+		if (true_target->is_member) {
+			out_of_date = (Boolean) OUT_OF_DATE_SEC(true_target->stat.time,
+				                                line->body.line.dependency_time);
+		} else {
+			out_of_date = (Boolean) OUT_OF_DATE(true_target->stat.time,
+				                            line->body.line.dependency_time);
+		}
+		if (build_unconditional || out_of_date){
+			if(!recheck_conditionals) {
+				line->body.line.is_out_of_date = true;
+			}
+		}
+		line->body.line.sccs_command = false;
+		line->body.line.target = true_target;
+		if(gnu_style) {
+
+			// set $< for explicit rule
+			if(line->body.line.dependencies != NULL) {
+				less = line->body.line.dependencies->name;
+			}
+
+			// set $* for explicit rule
+			Name			target_body;
+			Name			tt = true_target;
+			Property		member;
+			register wchar_t	*target_end;
+			register Dependency	suffix;
+			register int		suffix_length;
+			Wstring			targ_string;
+			Wstring			suf_string;
+
+			if (true_target->is_member &&
+			    ((member = get_prop(target->prop, member_prop)) !=
+			     NULL)) {
+				tt = member->body.member.member;
+			}
+			targ_string.init(tt);
+			target_end = targ_string.get_string() + tt->hash.length;
+			for (suffix = suffixes; suffix != NULL; suffix = suffix->next) {
+				suffix_length = suffix->name->hash.length;
+				suf_string.init(suffix->name);
+				if (tt->hash.length < suffix_length) {
+					continue;
+				} else if (!IS_WEQUALN(suf_string.get_string(),
+						(target_end - suffix_length),
+						suffix_length)) {
+					continue;
+				}
+				target_body = GETNAME(
+					targ_string.get_string(),
+					(int)(tt->hash.length - suffix_length)
+				);
+				line->body.line.star = target_body;
+			}
+
+			// set result = build_ok so that implicit rules are not used.
+			if(*result == build_dont_know) {
+				*result = build_ok;
+			}
+		}
+		if (less != NULL) {
+			line->body.line.less = less;
+		}
+	}
+
+	return false;
+}
+
+/*
+ *	dynamic_dependencies(target)
+ *
+ *	Checks if any dependency contains a macro ref
+ *	If so, it replaces the dependency with the expanded version.
+ *	Here, "$@" gets translated to target->string. That is
+ *	the current name on the left of the colon in the
+ *	makefile.  Thus,
+ *		xyz:	s.$@.c
+ *	translates into
+ *		xyz:	s.xyz.c
+ *
+ *	Also, "$(@F)" translates to the same thing without a preceeding
+ *	directory path (if one exists).
+ *	Note, to enter "$@" on a dependency line in a makefile
+ *	"$$@" must be typed. This is because make expands
+ *	macros in dependency lists upon reading them.
+ *	dynamic_dependencies() also expands file wildcards.
+ *	If there are any Shell meta characters in the name,
+ *	search the directory, and replace the dependency
+ *	with the set of files the pattern matches
+ *
+ *	Parameters:
+ *		target		Target to sanitize dependencies for
+ *
+ *	Global variables used:
+ *		c_at		The Name "@", used to set macro value
+ *		debug_level	Should we trace actions?
+ *		dot		The Name ".", used to read directory
+ *		recursion_level	Used for tracing
+ */
+void
+dynamic_dependencies(Name target)
+{
+	wchar_t			pattern[MAXPATHLEN];
+	register wchar_t	*p;
+	Property		line;
+	register Dependency	dependency;
+	register Dependency	*remove;
+	String_rec		string;
+	wchar_t			buffer[MAXPATHLEN];
+	register Boolean	set_at = false;
+	register wchar_t	*start;
+	Dependency		new_depe;
+	register Boolean	reuse_cell;
+	Dependency		first_member;
+	Name			directory;
+	Name			lib;
+	Name			member;
+	Property		prop;
+	Name			true_target = target;
+	wchar_t			*library;
+
+	if ((line = get_prop(target->prop, line_prop)) == NULL) {
+		return;
+	}
+	/* If the target is constructed from a "::" target we consider that */
+	if (target->has_target_prop) {
+		true_target = get_prop(target->prop,
+				       target_prop)->body.target.target;
+	}
+	/* Scan all dependencies and process the ones that contain "$" chars */
+	for (dependency = line->body.line.dependencies;
+	     dependency != NULL;
+	     dependency = dependency->next) {
+		if (!dependency->name->dollar) {
+			continue;
+		}
+		target->has_depe_list_expanded = true;
+
+		/* The make macro $@ is bound to the target name once per */
+		/* invocation of dynamic_dependencies() */
+		if (!set_at) {
+			(void) SETVAR(c_at, true_target, false);
+			set_at = true;
+		}
+		/* Expand this dependency string */
+		INIT_STRING_FROM_STACK(string, buffer);
+		expand_value(dependency->name, &string, false);
+		/* Scan the expanded string. It could contain whitespace */
+		/* which mean it expands to several dependencies */
+		start = string.buffer.start;
+		while (iswspace(*start)) {
+			start++;
+		}
+		/* Remove the cell (later) if the macro was empty */
+		if (start[0] == (int) nul_char) {
+			dependency->name = NULL;
+		}
+
+/* azv 10/26/95 to fix bug BID_1170218 */
+		if ((start[0] == (int) period_char) &&
+		    (start[1] == (int) slash_char)) {
+			start += 2;
+		}
+/* azv */
+
+		first_member = NULL;
+		/* We use the original dependency cell for the first */
+		/* dependency from the expansion */
+		reuse_cell = true;
+		/* We also have to deal with dependencies that expand to */
+		/* lib.a(members) notation */
+		for (p = start; *p != (int) nul_char; p++) {
+			if ((*p == (int) parenleft_char)) {
+				lib = GETNAME(start, p - start);
+				lib->is_member = true;
+				first_member = dependency;
+				start = p + 1;
+				while (iswspace(*start)) {
+					start++;
+				}
+				break;
+			}
+		}
+		do {
+		    /* First skip whitespace */
+			for (p = start; *p != (int) nul_char; p++) {
+				if ((*p == (int) nul_char) ||
+				    iswspace(*p) ||
+				    (*p == (int) parenright_char)) {
+					break;
+				}
+			}
+			/* Enter dependency from expansion */
+			if (p != start) {
+				/* Create new dependency cell if */
+				/* this is not the first dependency */
+				/* picked from the expansion */
+				if (!reuse_cell) {
+					new_depe = ALLOC(Dependency);
+					new_depe->next = dependency->next;
+					new_depe->automatic = false;
+					new_depe->stale = false;
+					new_depe->built = false;
+					dependency->next = new_depe;
+					dependency = new_depe;
+				}
+				reuse_cell = false;
+				/* Internalize the dependency name */
+				// tolik. Fix for bug 4110429: inconsistent expansion for macros that
+				// include "//" and "/./"
+				//dependency->name = GETNAME(start, p - start);
+				dependency->name = normalize_name(start, p - start);
+				if ((debug_level > 0) &&
+				    (first_member == NULL)) {
+					(void) printf(catgets(catd, 1, 25, "%*sDynamic dependency `%s' for target `%s'\n"),
+						      recursion_level,
+						      "",
+						      dependency->name->string_mb,
+						      true_target->string_mb);
+				}
+				for (start = p; iswspace(*start); start++);
+				p = start;
+			}
+		} while ((*p != (int) nul_char) &&
+			 (*p != (int) parenright_char));
+		/* If the expansion was of lib.a(members) format we now */
+		/* enter the proper member cells */
+		if (first_member != NULL) {
+			/* Scan the new dependencies and transform them from */
+			/* "foo" to "lib.a(foo)" */
+			for (; 1; first_member = first_member->next) {
+				/* Build "lib.a(foo)" name */
+				INIT_STRING_FROM_STACK(string, buffer);
+				APPEND_NAME(lib,
+					      &string,
+					      (int) lib->hash.length);
+				append_char((int) parenleft_char, &string);
+				APPEND_NAME(first_member->name,
+					      &string,
+					      FIND_LENGTH);
+				append_char((int) parenright_char, &string);
+				member = first_member->name;
+				/* Replace "foo" with "lib.a(foo)" */
+				first_member->name =
+				  GETNAME(string.buffer.start, FIND_LENGTH);
+				if (string.free_after_use) {
+					retmem(string.buffer.start);
+				}
+				if (debug_level > 0) {
+					(void) printf(catgets(catd, 1, 26, "%*sDynamic dependency `%s' for target `%s'\n"),
+						      recursion_level,
+						      "",
+						      first_member->name->
+						      string_mb,
+						      true_target->string_mb);
+				}
+				first_member->name->is_member = lib->is_member;
+				/* Add member property to member */
+				prop = maybe_append_prop(first_member->name,
+							 member_prop);
+				prop->body.member.library = lib;
+				prop->body.member.entry = NULL;
+				prop->body.member.member = member;
+				if (first_member == dependency) {
+					break;
+				}
+			}
+		}
+	}
+	Wstring wcb;
+	/* Then scan all the dependencies again. This time we want to expand */
+	/* shell file wildcards */
+	for (remove = &line->body.line.dependencies, dependency = *remove;
+	     dependency != NULL;
+	     dependency = *remove) {
+		if (dependency->name == NULL) {
+			dependency = *remove = (*remove)->next;
+			continue;
+		}
+		/* If dependency name string contains shell wildcards */
+		/* replace the name with the expansion */
+		if (dependency->name->wildcard) {
+#ifdef NSE
+	                nse_wildcard(target->string, dependency->name->string);
+#endif
+			wcb.init(dependency->name);
+			if ((start = (wchar_t *) wschr(wcb.get_string(),
+					   (int) parenleft_char)) != NULL) {
+				/* lib(*) type pattern */
+				library = buffer;
+				(void) wsncpy(buffer,
+					      wcb.get_string(),
+					      start - wcb.get_string());
+				buffer[start-wcb.get_string()] =
+				  (int) nul_char;
+				(void) wsncpy(pattern,
+					      start + 1,
+(int) (dependency->name->hash.length-(start-wcb.get_string())-2));
+				pattern[dependency->name->hash.length -
+					(start-wcb.get_string()) - 2] =
+					  (int) nul_char;
+			} else {
+				library = NULL;
+				(void) wsncpy(pattern,
+					      wcb.get_string(),
+					      (int) dependency->name->hash.length);
+				pattern[dependency->name->hash.length] =
+				  (int) nul_char;
+			}
+			start = (wchar_t *) wsrchr(pattern, (int) slash_char);
+			if (start == NULL) {
+				directory = dot;
+				p = pattern;
+			} else {
+				directory = GETNAME(pattern, start-pattern);
+				p = start+1;
+			}
+			/* The expansion is handled by the read_dir() routine*/
+			if (read_dir(directory, p, line, library)) {
+				*remove = (*remove)->next;
+			} else {
+				remove = &dependency->next;
+			}
+		} else {
+			remove = &dependency->next;
+		}
+        }
+
+	/* Then unbind $@ */
+	(void) SETVAR(c_at, (Name) NULL, false);
+}
+
+/*
+ * DONE.
+ *
+ *	run_command(line)
+ *
+ *	Takes one Cmd_line and runs the commands from it.
+ *
+ *	Return value:
+ *				Indicates if the command failed or not
+ *
+ *	Parameters:
+ *		line		The command line to run
+ *
+ *	Global variables used:
+ *		commands_done	Set if we do run command
+ *		current_line	Set to the line we run a command from
+ *		current_target	Set to the target we run a command for
+ *		file_number	Used to form temp file name
+ *		keep_state	Indicates that .KEEP_STATE is on
+ *		make_state	The Name ".make.state", used to check timestamp
+ *		parallel	True if currently building in parallel
+ *		parallel_process_cnt Count of parallel processes running
+ *		quest		Indicates that make -q is on
+ *		rewrite_statefile Set if we do run a command
+ *		sunpro_dependencies The Name "SUNPRO_DEPENDENCIES", set value
+ *		temp_file_directory Used to form temp fie name
+ *		temp_file_name	Set to the name of the temp file
+ *		touch		Indicates that make -t is on
+ */
+static Doname
+run_command(register Property line, Boolean)
+{
+	register Doname		result = build_ok;
+	register Boolean	remember_only = false;
+	register Name		target = line->body.line.target;
+	wchar_t			*string;
+	char			tmp_file_path[MAXPATHLEN];
+
+	if (!line->body.line.is_out_of_date && target->rechecking_target) {
+		target->rechecking_target = false;
+		return build_ok;
+	}
+
+	/*
+	 * Build the command if we know the target is out of date,
+	 * or if we want to check cmd consistency.
+	 */
+	if (line->body.line.is_out_of_date || keep_state) {
+		/* Hack for handling conditional macros in DMake. */
+		if (!line->body.line.dont_rebuild_command_used) {
+			build_command_strings(target, line);
+		}
+	}
+	/* Never mind */
+	if (!line->body.line.is_out_of_date) {
+		return build_ok;
+	}
+	/* If quest, then exit(1) because the target is out of date */
+	if (quest) {
+		if (posix) {
+#ifdef TEAMWARE_MAKE_CMN
+			result = execute_parallel(line, true);
+#else
+			result = execute_serial(line);
+#endif
+		}
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+		exit_status = 1;
+#endif
+		exit(1);
+	}
+	/* We actually had to do something this time */
+	rewrite_statefile = commands_done = true;
+	/*
+	 * If this is an sccs command, we have to do some extra checking
+	 * and possibly complain. If the file can't be gotten because it's
+	 * checked out, we complain and behave as if the command was
+	 * executed eventhough we ignored the command.
+	 */
+	if (!touch &&
+	    line->body.line.sccs_command &&
+	    (target->stat.time != file_doesnt_exist) &&
+	    ((target->stat.mode & 0222) != 0)) {
+		fatal(catgets(catd, 1, 27, "%s is writable so it cannot be sccs gotten"),
+		      target->string_mb);
+		target->has_complained = remember_only = true;
+	}
+	/*
+	 * If KEEP_STATE is on, we make sure we have the timestamp for
+	 * .make.state. If .make.state changes during the command run,
+	 * we reread .make.state after the command. We also setup the
+	 * environment variable that asks utilities to report dependencies.
+	 */
+	if (!touch &&
+	    keep_state &&
+	    !remember_only) {
+		(void) exists(make_state);
+		if((strlen(temp_file_directory) == 1) && 
+			(temp_file_directory[0] == '/')) {
+		   tmp_file_path[0] = '\0';
+		} else {
+		   strcpy(tmp_file_path, temp_file_directory);
+		}
+		sprintf(mbs_buffer,
+				NOCATGETS("%s/.make.dependency.%08x.%d.%d"),
+			        tmp_file_path,
+			        hostid,
+			        getpid(),
+			        file_number++);
+		MBSTOWCS(wcs_buffer, mbs_buffer);
+		Boolean fnd;
+		temp_file_name = getname_fn(wcs_buffer, FIND_LENGTH, false, &fnd);
+		temp_file_name->stat.is_file = true;
+		int len = 2*MAXPATHLEN + strlen(target->string_mb) + 2;
+		wchar_t *to = string = ALLOC_WC(len);
+		for (wchar_t *from = wcs_buffer; *from != (int) nul_char; ) {
+			if (*from == (int) space_char) {
+				*to++ = (int) backslash_char;
+			}
+			*to++ = *from++;
+		}
+		*to++ = (int) space_char;
+		MBSTOWCS(to, target->string_mb);
+		Name sprodep_name = getname_fn(string, FIND_LENGTH, false, &fnd);
+		(void) SETVAR(sunpro_dependencies,
+			      sprodep_name,
+			      false);
+		retmem(string);
+	} else {
+		temp_file_name = NULL;
+	}
+
+	/*
+	 * In case we are interrupted, we need to know what was going on.
+	 */
+	current_target = target;
+	/*
+	 * We also need to be able to save an empty command instead of the
+	 * interrupted one in .make.state.
+	 */
+	current_line = line;
+	if (remember_only) {
+		/* Empty block!!! */
+	} else if (touch) {
+		result = touch_command(line, target, result);
+		if (posix) {
+#ifdef TEAMWARE_MAKE_CMN
+			result = execute_parallel(line, true);
+#else
+			result = execute_serial(line);
+#endif
+		}
+	} else {
+		/*
+		 * If this is not a touch run, we need to execute the
+		 * proper command(s) for the target.
+		 */
+#ifdef TEAMWARE_MAKE_CMN
+		if (parallel) {
+			if (!parallel_ok(target, true)) {
+				/*
+				 * We are building in parallel, but
+				 * this target must be built in serial.
+				 */
+				/*
+				 * If nothing else is building,
+				 * do this one, else wait.
+				 */
+				if (parallel_process_cnt == 0) {
+#ifdef TEAMWARE_MAKE_CMN
+					result = execute_parallel(line, true, target->localhost);
+#else
+					result = execute_serial(line);
+#endif
+				} else {
+					current_target = NULL;
+					current_line = NULL;
+/*
+					line->body.line.command_used = NULL;
+ */
+					line->body.line.dont_rebuild_command_used = true;
+					return build_serial;
+				}
+			} else {
+				result = execute_parallel(line, false);
+				switch (result) {
+				case build_running:
+					return build_running;
+				case build_serial:
+					if (parallel_process_cnt == 0) {
+#ifdef TEAMWARE_MAKE_CMN
+						result = execute_parallel(line, true, target->localhost);
+#else
+						result = execute_serial(line);
+#endif
+					} else {
+						current_target = NULL;
+						current_line = NULL;
+						target->parallel = false;
+						line->body.line.command_used =
+						  			NULL;
+						return build_serial;
+					}
+				}
+			}
+		} else {
+#endif
+#ifdef TEAMWARE_MAKE_CMN
+			result = execute_parallel(line, true, target->localhost);
+#else
+			result = execute_serial(line);
+#endif
+#ifdef TEAMWARE_MAKE_CMN
+		}
+#endif
+	}
+	temp_file_name = NULL;
+	if (report_dependencies_level == 0){
+		update_target(line, result);
+	}
+	current_target = NULL;
+	current_line = NULL;
+	return result;
+}
+
+/*
+ *	execute_serial(line)
+ *
+ *	Runs thru the command line for the target and
+ *	executes the rules one by one.
+ *
+ *	Return value:
+ *				The result of the command build
+ *
+ *	Parameters:	
+ *		line		The command to execute
+ *
+ *	Static variables used:
+ *
+ *	Global variables used:
+ *		continue_after_error -k flag
+ *		do_not_exec_rule -n flag
+ *		report_dependencies -P flag
+ *		silent		Don't echo commands before executing
+ *		temp_file_name	Temp file for auto dependencies
+ *		vpath_defined	If true, translate path for command
+ */
+Doname
+execute_serial(Property line)
+{
+	int			child_pid = 0;
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+	Avo_MToolJobResultMsg	*job_result_msg;
+	RWCollectable		*xdr_msg;
+#endif
+	Boolean			printed_serial;
+	Doname			result = build_ok;
+	Cmd_line		rule, cmd_tail, command = NULL;
+	char			mbstring[MAXPATHLEN];
+	int			filed;
+	Name			target = line->body.line.target;
+
+	SEND_MTOOL_MSG(
+		if (!sent_rsrc_info_msg) {
+			if (userName[0] == '\0') {
+				avo_get_user(userName, NULL);
+			}
+			if (hostName[0] == '\0') {
+				strcpy(hostName, avo_hostname());
+			}
+			send_rsrc_info_msg(1, hostName, userName);
+			sent_rsrc_info_msg = 1;
+		}
+		send_job_start_msg(line);
+		job_result_msg = new Avo_MToolJobResultMsg();
+	);
+
+	target->has_recursive_dependency = false;
+	// We have to create a copy of the rules chain for processing because
+	// the original one can be destroyed during .make.state file rereading.
+	for (rule = line->body.line.command_used;
+	     rule != NULL;
+	     rule = rule->next) {
+		if (command == NULL) {
+			command = cmd_tail = ALLOC(Cmd_line);
+		} else {
+			cmd_tail->next = ALLOC(Cmd_line);
+			cmd_tail = cmd_tail->next;
+		}
+		*cmd_tail = *rule;
+	}
+	if (command) {
+		cmd_tail->next = NULL;
+	}
+	for (rule = command; rule != NULL; rule = rule->next) {
+		if (posix && (touch || quest) && !rule->always_exec) {
+			continue;
+		}
+		if (vpath_defined) {
+			rule->command_line =
+			  vpath_translation(rule->command_line);
+		}
+		/* Echo command line, maybe. */
+		if ((rule->command_line->hash.length > 0) &&
+		    !silent &&
+		    (!rule->silent || do_not_exec_rule) &&
+		    (report_dependencies_level == 0)) {
+			(void) printf("%s\n", rule->command_line->string_mb);
+			SEND_MTOOL_MSG(
+				job_result_msg->appendOutput(AVO_STRDUP(rule->command_line->string_mb));
+			);
+		}
+		if (rule->command_line->hash.length > 0) {
+			SEND_MTOOL_MSG(
+				(void) sprintf(mbstring,
+						NOCATGETS("%s/make.stdout.%d.%d.XXXXXX"),
+						tmpdir,
+						getpid(),
+						file_number++);
+
+				int tmp_fd = mkstemp(mbstring);
+				if(tmp_fd) {
+					(void) close(tmp_fd);
+				}
+
+				stdout_file = strdup(mbstring);
+				stderr_file = NULL;
+				child_pid = pollResults(stdout_file,
+							(char *)NULL,
+							(char *)NULL);
+			);
+			/* Do assignment if command line prefixed with "=" */
+			if (rule->assign) {
+				result = build_ok;
+				do_assign(rule->command_line, target);
+			} else if (report_dependencies_level == 0) {
+				/* Execute command line. */
+#ifdef DISTRIBUTED
+				setvar_envvar((Avo_DoJobMsg *)NULL);
+#else
+				setvar_envvar();
+#endif
+				result = dosys(rule->command_line,
+				               (Boolean) rule->ignore_error,
+				               (Boolean) rule->make_refd,
+				               /* ds 98.04.23 bug #4085164. make should always show error messages */
+				               false,
+				               /* BOOLEAN(rule->silent &&
+				                       rule->ignore_error), */
+				               (Boolean) rule->always_exec,
+				               target,
+				               send_mtool_msgs);
+#ifdef NSE
+				nse_did_recursion= false;
+#endif
+				check_state(temp_file_name);
+#ifdef NSE
+				nse_check_cd(line);
+#endif
+			}
+			SEND_MTOOL_MSG(
+				append_job_result_msg(job_result_msg);
+				if (child_pid > 0) {
+					kill(child_pid, SIGUSR1);
+					while (!((waitpid(child_pid, 0, 0) == -1)
+						&& (errno == ECHILD)));
+				}
+				child_pid = 0;
+				(void) unlink(stdout_file);
+				retmem_mb(stdout_file);
+				stdout_file = NULL;
+			);
+		} else {
+			result = build_ok;
+		}
+		if (result == build_failed) {
+			if (silent || rule->silent) {
+				(void) printf(catgets(catd, 1, 242, "The following command caused the error:\n%s\n"),
+				              rule->command_line->string_mb);
+				SEND_MTOOL_MSG(
+					job_result_msg->appendOutput(AVO_STRDUP(catgets(catd, 1, 243, "The following command caused the error:")));
+					job_result_msg->appendOutput(AVO_STRDUP(rule->command_line->string_mb));
+				);
+			}
+			if (!rule->ignore_error && !ignore_errors) {
+				if (!continue_after_error) {
+					SEND_MTOOL_MSG(
+						job_result_msg->setResult(job_msg_id, (result == build_ok) ? 0 : 1, DONE);
+						xdr_msg = (RWCollectable*)
+							job_result_msg;
+						xdr(&xdrs, xdr_msg);
+						(void) fflush(mtool_msgs_fp);
+						delete job_result_msg;
+					);
+					fatal(catgets(catd, 1, 244, "Command failed for target `%s'"),
+					      target->string_mb);
+				}
+				/*
+				 * Make sure a failing command is not
+				 * saved in .make.state.
+				 */
+				line->body.line.command_used = NULL;
+				break;
+			} else {
+				result = build_ok;
+			}
+		}
+	}
+	for (rule = command; rule != NULL; rule = cmd_tail) {
+		cmd_tail = rule->next;
+		free(rule);
+	}
+	command = NULL;
+	SEND_MTOOL_MSG(
+		job_result_msg->setResult(job_msg_id, (result == build_ok) ? 0 : 1, DONE);
+		xdr_msg = (RWCollectable*) job_result_msg;
+		xdr(&xdrs, xdr_msg);
+		(void) fflush(mtool_msgs_fp);
+
+		delete job_result_msg;
+	);
+	if (temp_file_name != NULL) {
+		free_name(temp_file_name);
+	}
+        temp_file_name = NULL;
+
+	Property spro = get_prop(sunpro_dependencies->prop, macro_prop);
+	if(spro != NULL) {
+		Name val = spro->body.macro.value;
+		if(val != NULL) {
+			free_name(val);
+			spro->body.macro.value = NULL;
+		}
+	}
+	spro = get_prop(sunpro_dependencies->prop, env_mem_prop);
+	if(spro) {
+		char *val = spro->body.env_mem.value;
+		if(val != NULL) {
+			/* 
+			 * Do not return memory allocated for SUNPRO_DEPENDENCIES
+			 * It will be returned in setvar_daemon() in macro.cc 
+			 */
+			//	retmem_mb(val);
+			spro->body.env_mem.value = NULL;
+		}
+	}
+	
+        return result;
+}
+
+
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+
+/*
+ * Create and send an Avo_MToolRsrcInfoMsg.
+ */
+void
+send_rsrc_info_msg(int max_jobs, char *hostname, char *username)
+{
+	static int		first = 1;
+	Avo_MToolRsrcInfoMsg	*msg;
+	RWSlistCollectables	server_list;
+	Avo_ServerState		*server_state;
+	RWCollectable		*xdr_msg;
+
+	if (!first) {
+		return;
+	}
+	first = 0;
+
+	create_xdrs_ptr();
+
+	server_state = new Avo_ServerState(max_jobs, hostname, username);
+	server_list.append(server_state);
+	msg = new Avo_MToolRsrcInfoMsg(&server_list);
+
+	xdr_msg = (RWCollectable *)msg;
+	xdr(get_xdrs_ptr(), xdr_msg);
+	(void) fflush(get_mtool_msgs_fp());
+
+	delete server_state;
+	delete msg;
+}
+
+/*
+ * Create and send an Avo_MToolJobStartMsg.
+ */
+void
+send_job_start_msg(Property line)
+{
+	int			cmd_options = 0;
+	Avo_MToolJobStartMsg	*msg;
+	Cmd_line		rule;
+	Name			target = line->body.line.target;
+	RWCollectable		*xdr_msg;
+
+	if (userName[0] == '\0') {
+		avo_get_user(userName, NULL);
+	}
+	if (hostName[0] == '\0') {
+		strcpy(hostName, avo_hostname());
+	}
+
+	msg = new Avo_MToolJobStartMsg();
+	msg->setJobId(++job_msg_id);
+	msg->setTarget(AVO_STRDUP(target->string_mb));
+	msg->setHost(AVO_STRDUP(hostName));
+	msg->setUser(AVO_STRDUP(userName));
+
+        for (rule = line->body.line.command_used;
+             rule != NULL;
+             rule = rule->next) {
+		if (posix && (touch || quest) && !rule->always_exec) {
+			continue;
+		}
+                if (vpath_defined) {
+                        rule->command_line =
+                          vpath_translation(rule->command_line);
+                }
+		cmd_options = 0;
+		if (rule->ignore_error || ignore_errors) {
+			cmd_options |= ignore_mask;
+		}
+		if (rule->silent || silent) {
+			cmd_options |= silent_mask;
+		}
+		if (rule->command_line->meta) {
+			cmd_options |= meta_mask;
+		}
+                if (!touch && (rule->command_line->hash.length > 0)) {
+			msg->appendCmd(new Avo_DmakeCommand(rule->command_line->string_mb, cmd_options));
+                }
+        }
+
+	xdr_msg = (RWCollectable*) msg;
+	xdr(&xdrs, xdr_msg);
+	(void) fflush(mtool_msgs_fp);
+
+/* tolik, 08/39/2002.
+   I commented out this code because it causes using unallocated memory.
+	delete msg;
+*/
+}
+
+/*
+ * Append the stdout/err to Avo_MToolJobResultMsg.
+ */
+static void
+append_job_result_msg(Avo_MToolJobResultMsg *job_result_msg)
+{
+	FILE		*fp;
+	char		line[MAXPATHLEN];
+	char		stdout_file2[MAXPATHLEN];
+
+	if (stdout_file != NULL) {
+		fp = fopen(stdout_file, "r");
+		if (fp == NULL) {
+			/* Hmmm... what should we do here? */
+			warning(catgets(catd, 1, 326, "fopen() of stdout_file failed. Output may be lost"));
+			return;
+		}
+		while (fgets(line, MAXPATHLEN, fp) != NULL) {
+			if (line[strlen(line) - 1] == '\n') {
+				line[strlen(line) - 1] = '\0';
+			}
+			job_result_msg->appendOutput(AVO_STRDUP(line));
+		}
+		(void) fclose(fp);
+		us_sleep(STAT_RETRY_SLEEP_TIME);
+	} else {
+		/* Hmmm... stdout_file shouldn't be NULL */
+		warning(catgets(catd, 1, 327, "Internal stdout_file variable shouldn't be NULL. Output may be lost"));
+	}
+}
+#endif /* TEAMWARE_MAKE_CMN */
+
+/*
+ *	vpath_translation(cmd)
+ *
+ *	Translates one command line by
+ *	checking each word. If the word has an alias it is translated.
+ *
+ *	Return value:
+ *				The translated command
+ *
+ *	Parameters:
+ *		cmd		Command to translate
+ *
+ *	Global variables used:
+ */
+Name
+vpath_translation(register Name cmd)
+{
+	wchar_t			buffer[STRING_BUFFER_LENGTH];
+	String_rec		new_cmd;
+	wchar_t			*p;
+	wchar_t			*start;
+
+	if (!vpath_defined || (cmd == NULL) || (cmd->hash.length == 0)) {
+		return cmd;
+	}
+	INIT_STRING_FROM_STACK(new_cmd, buffer);
+
+	Wstring wcb(cmd);
+	p = wcb.get_string();
+
+	while (*p != (int) nul_char) {
+		while (iswspace(*p) && (*p != (int) nul_char)) {
+			append_char(*p++, &new_cmd);
+		}
+		start = p;
+		while (!iswspace(*p) && (*p != (int) nul_char)) {
+			p++;
+		}
+		cmd = GETNAME(start, p - start);
+		if (cmd->has_vpath_alias_prop) {
+			cmd = get_prop(cmd->prop, vpath_alias_prop)->
+						body.vpath_alias.alias;
+			APPEND_NAME(cmd,
+				      &new_cmd,
+				      (int) cmd->hash.length);
+		} else {
+			append_string(start, &new_cmd, p - start);
+		}
+	}
+	cmd = GETNAME(new_cmd.buffer.start, FIND_LENGTH);
+	if (new_cmd.free_after_use) {
+		retmem(new_cmd.buffer.start);
+	}
+	return cmd;
+}
+
+/*
+ *	check_state(temp_file_name)
+ *
+ *	Reads and checks the state changed by the previously executed command.
+ *
+ *	Parameters:
+ *		temp_file_name	The auto dependency temp file
+ *
+ *	Global variables used:
+ */
+void
+check_state(Name temp_file_name)
+{
+	if (!keep_state) {
+		return;
+	}
+
+	/*
+	 * Then read the temp file that now might 
+	 * contain dependency reports from utilities 
+	 */
+	read_dependency_file(temp_file_name);
+
+	/*
+	 * And reread .make.state if it
+	 * changed (the command ran recursive makes) 
+	 */
+	check_read_state_file();
+	if (temp_file_name != NULL) {
+		(void) unlink(temp_file_name->string_mb);
+	}
+}
+
+/*
+ *	read_dependency_file(filename)
+ *
+ *	Read the temp file used for reporting dependencies to make
+ *
+ *	Parameters:
+ *		filename	The name of the file with the state info
+ *
+ *	Global variables used:
+ *		makefile_type	The type of makefile being read
+ *		read_trace_level Debug flag
+ *		temp_file_number The always increasing number for unique files
+ *		trace_reader	Debug flag
+ */
+static void
+read_dependency_file(register Name filename)
+{
+	register Makefile_type	save_makefile_type;
+
+	if (filename == NULL) {
+		return;
+	}
+	filename->stat.time = file_no_time;
+	if (exists(filename) > file_doesnt_exist) {
+		save_makefile_type = makefile_type;
+		makefile_type = reading_cpp_file;
+		if (read_trace_level > 1) {
+			trace_reader = true;
+		}
+		temp_file_number++;
+		(void) read_simple_file(filename,
+					false,
+					false,
+					false,
+					false,
+					false,
+					false);
+		trace_reader = false;
+		makefile_type = save_makefile_type;
+	}
+}
+
+/*
+ *	check_read_state_file()
+ *
+ *	Check if .make.state has changed
+ *	If it has we reread it
+ *
+ *	Parameters:
+ *
+ *	Global variables used:
+ *		make_state	Make state file name
+ *		makefile_type	Type of makefile being read
+ *		read_trace_level Debug flag
+ *		trace_reader	Debug flag
+ */
+static void
+check_read_state_file(void)
+{
+	timestruc_t		previous = make_state->stat.time;
+	register Makefile_type	save_makefile_type;
+	register Property	makefile;
+
+	make_state->stat.time = file_no_time;
+	if ((exists(make_state) == file_doesnt_exist) ||
+	    (make_state->stat.time == previous)) {
+		return;
+	}
+	save_makefile_type = makefile_type;
+	makefile_type = rereading_statefile;
+	/* Make sure we clear the old cached contents of .make.state */
+	makefile = maybe_append_prop(make_state, makefile_prop);
+	if (makefile->body.makefile.contents != NULL) {
+		retmem(makefile->body.makefile.contents);
+		makefile->body.makefile.contents = NULL;
+	}
+	if (read_trace_level > 1) {
+		trace_reader = true;
+	}
+	temp_file_number++;
+	(void) read_simple_file(make_state,
+				false,
+				false,
+				false,
+				false,
+				false,
+				true);
+	trace_reader = false;
+	makefile_type = save_makefile_type;
+}
+
+/*
+ *	do_assign(line, target)
+ *
+ *	Handles runtime assignments for command lines prefixed with "=".
+ *
+ *	Parameters:
+ *		line		The command that contains an assignment
+ *		target		The Name of the target, used for error reports
+ *
+ *	Global variables used:
+ *		assign_done	Set to indicate doname needs to reprocess
+ */
+static void
+do_assign(register Name line, register Name target)
+{
+	Wstring wcb(line);
+	register wchar_t	*string = wcb.get_string();
+	register wchar_t	*equal;
+	register Name		name;
+	register Boolean	append = false;
+
+	/*
+	 * If any runtime assignments are done, doname() must reprocess all
+	 * targets in the future since the macro values used to build the
+	 * command lines for the targets might have changed.
+	 */
+	assign_done = true;
+	/* Skip white space. */
+	while (iswspace(*string)) {
+		string++;
+	}
+	equal = string;
+	/* Find "+=" or "=". */
+	while (!iswspace(*equal) &&
+	       (*equal != (int) plus_char) &&
+	       (*equal != (int) equal_char)) {
+		equal++;
+	}
+	/* Internalize macro name. */
+	name = GETNAME(string, equal - string);
+	/* Skip over "+=" "=". */
+	while (!((*equal == (int) nul_char) ||
+		 (*equal == (int) equal_char) ||
+		 (*equal == (int) plus_char))) {
+		equal++;
+	}
+	switch (*equal) {
+	case nul_char:
+		fatal(catgets(catd, 1, 31, "= expected in rule `%s' for target `%s'"),
+		      line->string_mb,
+		      target->string_mb);
+	case plus_char:
+		append = true;
+		equal++;
+		break;
+	}
+	equal++;
+	/* Skip over whitespace in front of value. */
+	while (iswspace(*equal)) {
+		equal++;
+	}
+	/* Enter new macro value. */
+	enter_equal(name,
+		    GETNAME(equal, wcb.get_string() + line->hash.length - equal),
+		    append);
+}
+
+/*
+ *	build_command_strings(target, line)
+ *
+ *	Builds the command string to used when
+ *	building a target. If the string is different from the previous one
+ *	is_out_of_date is set.
+ *
+ *	Parameters:
+ *		target		Target to build commands for
+ *		line		Where to stuff result
+ *
+ *	Global variables used:
+ *		c_at		The Name "@", used to set macro value
+ *		command_changed	Set if command is different from old
+ *		debug_level	Should we trace activities?
+ *		do_not_exec_rule Always echo when running -n
+ *		empty_name	The Name "", used for empty rule
+ *		funny		Semantics of characters
+ *		ignore_errors	Used to init field for line
+ *		is_conditional	Set to false befor evaling macro, checked
+ *				after expanding macros
+ *		keep_state	Indicates that .KEEP_STATE is on
+ *		make_word_mentioned Set by macro eval, inits field for cmd
+ *		query		The Name "?", used to set macro value
+ *		query_mentioned	Set by macro eval, inits field for cmd
+ *		recursion_level	Used for tracing
+ *		silent		Used to init field for line
+ */
+static void
+build_command_strings(Name target, register Property line)
+{
+	String_rec		command_line;
+	register Cmd_line	command_template = line->body.line.command_template;
+	register Cmd_line	*insert = &line->body.line.command_used;
+	register Cmd_line	used = *insert;
+	wchar_t			buffer[STRING_BUFFER_LENGTH];
+	wchar_t			*start;
+	Name			new_command_line;
+	register Boolean	new_command_longer = false;
+	register Boolean	ignore_all_command_dependency = true;
+	Property		member;
+	static Name		less_name;
+	static Name		percent_name;
+	static Name		star;
+	Name			tmp_name;
+
+	if (less_name == NULL) {
+		MBSTOWCS(wcs_buffer, "<");
+		less_name = GETNAME(wcs_buffer, FIND_LENGTH);
+		MBSTOWCS(wcs_buffer, "%");
+		percent_name = GETNAME(wcs_buffer, FIND_LENGTH);
+		MBSTOWCS(wcs_buffer, "*");
+		star = GETNAME(wcs_buffer, FIND_LENGTH);
+	}
+
+	/* We have to check if a target depends on conditional macros */
+	/* Targets that do must be reprocessed by doname() each time around */
+	/* since the macro values used when building the target might have */
+	/* changed */
+	conditional_macro_used = false;
+	/* If we are building a lib.a(member) target $@ should be bound */
+	/* to lib.a */
+	if (target->is_member &&
+	    ((member = get_prop(target->prop, member_prop)) != NULL)) {
+		target = member->body.member.library;
+	}
+	/* If we are building a "::" help target $@ should be bound to */
+	/* the real target name */
+	/* A lib.a(member) target is never :: */
+	if (target->has_target_prop) {
+		target = get_prop(target->prop, target_prop)->
+		  body.target.target;
+	}
+	/* Bind the magic macros that make supplies */
+	tmp_name = target;
+	if(tmp_name != NULL) {
+		if (tmp_name->has_vpath_alias_prop) {
+			tmp_name = get_prop(tmp_name->prop, vpath_alias_prop)->
+					body.vpath_alias.alias;
+		}
+	}
+	(void) SETVAR(c_at, tmp_name, false);
+
+	tmp_name = line->body.line.star;
+	if(tmp_name != NULL) {
+		if (tmp_name->has_vpath_alias_prop) {
+			tmp_name = get_prop(tmp_name->prop, vpath_alias_prop)->
+					body.vpath_alias.alias;
+		}
+	}
+	(void) SETVAR(star, tmp_name, false);
+
+	tmp_name = line->body.line.less;
+	if(tmp_name != NULL) {
+		if (tmp_name->has_vpath_alias_prop) {
+			tmp_name = get_prop(tmp_name->prop, vpath_alias_prop)->
+					body.vpath_alias.alias;
+		}
+	}
+	(void) SETVAR(less_name, tmp_name, false);
+
+	tmp_name = line->body.line.percent;
+	if(tmp_name != NULL) {
+		if (tmp_name->has_vpath_alias_prop) {
+			tmp_name = get_prop(tmp_name->prop, vpath_alias_prop)->
+					body.vpath_alias.alias;
+		}
+	}
+	(void) SETVAR(percent_name, tmp_name, false);
+
+	/* $? is seldom used and it is expensive to build */
+	/* so we store the list form and build the string on demand */
+	Chain query_list = NULL;
+	Chain *query_list_tail = &query_list;
+
+	for (Chain ch = line->body.line.query; ch != NULL; ch = ch->next) {
+		*query_list_tail = ALLOC(Chain);
+		(*query_list_tail)->name = ch->name;
+		if ((*query_list_tail)->name->has_vpath_alias_prop) {
+			(*query_list_tail)->name =
+				get_prop((*query_list_tail)->name->prop,
+					vpath_alias_prop)->body.vpath_alias.alias;
+		}
+		(*query_list_tail)->next = NULL;
+		query_list_tail = &(*query_list_tail)->next;
+	}
+	(void) setvar_daemon(query,
+			     (Name) query_list,
+			     false,
+			     chain_daemon,
+                             false,
+                             debug_level);
+
+	/* build $^ */
+	Chain hat_list = NULL;
+	Chain *hat_list_tail = &hat_list;
+
+	for (Dependency dependency = line->body.line.dependencies; 
+		dependency != NULL;
+		dependency = dependency->next) {
+		/* skip automatic dependencies */
+		if (!dependency->automatic) {
+			if ((dependency->name != force) &&
+				(dependency->stale == false)) {
+				*hat_list_tail = ALLOC(Chain);
+			
+				if (dependency->name->is_member &&
+					(get_prop(dependency->name->prop, member_prop) != NULL)) {
+					(*hat_list_tail)->name = 
+							get_prop(dependency->name->prop,
+								member_prop)->body.member.member;
+				} else {
+					(*hat_list_tail)->name = dependency->name;
+				}
+
+				if((*hat_list_tail)->name != NULL) {
+					if ((*hat_list_tail)->name->has_vpath_alias_prop) {
+						(*hat_list_tail)->name =
+							get_prop((*hat_list_tail)->name->prop,
+								vpath_alias_prop)->body.vpath_alias.alias;
+					}
+				}
+
+				(*hat_list_tail)->next = NULL;
+				hat_list_tail = &(*hat_list_tail)->next;
+			}
+		}
+	}
+	(void) setvar_daemon(hat,
+			     (Name) hat_list,
+			     false,
+			     chain_daemon,
+                             false,
+                             debug_level);
+
+/* We have two command sequences we need to handle */
+/* The old one that we probably read from .make.state */
+/* and the new one we are building that will replace the old one */
+/* Even when KEEP_STATE is not on we build a new command sequence and store */
+/* it in the line prop. This command sequence is then executed by */
+/* run_command(). If KEEP_STATE is on it is also later written to */
+/* .make.state. The routine replaces the old command line by line with the */
+/* new one trying to reuse Cmd_lines */
+
+	/* If there is no old command_used we have to start creating */
+	/* Cmd_lines to keep the new cmd in */
+	if (used == NULL) {
+		new_command_longer = true;
+		*insert = used = ALLOC(Cmd_line);
+		used->next = NULL;
+		used->command_line = NULL;
+		insert = &used->next;
+	}
+	/* Run thru the template for the new command and build the expanded */
+	/* new command lines */
+	for (;
+	     command_template != NULL;
+	     command_template = command_template->next, insert = &used->next, used = *insert) {
+		/* If there is no old command_used Cmd_line we need to */
+		/* create one and say that cmd consistency failed */
+		if (used == NULL) {
+			new_command_longer = true;
+			*insert = used = ALLOC(Cmd_line);
+			used->next = NULL;
+			used->command_line = empty_name;
+		}
+		/* Prepare the Cmd_line for the processing */
+		/* The command line prefixes "@-=?" are stripped and that */
+		/* information is saved in the Cmd_line */
+		used->assign = false;
+		used->ignore_error = ignore_errors;
+		used->silent = silent;
+		used->always_exec = false;
+		/* Expand the macros in the command line */
+		INIT_STRING_FROM_STACK(command_line, buffer);
+		make_word_mentioned =
+		  query_mentioned =
+		    false;
+		expand_value(command_template->command_line, &command_line, true);
+		/* If the macro $(MAKE) is mentioned in the command */
+		/* "make -n" runs actually execute the command */
+		used->make_refd = make_word_mentioned;
+		used->ignore_command_dependency = query_mentioned;
+		/* Strip the prefixes */
+		start = command_line.buffer.start;
+		for (;
+		     iswspace(*start) ||
+		     (get_char_semantics_value(*start) & (int) command_prefix_sem);
+		     start++) {
+			switch (*start) {
+			case question_char:
+				used->ignore_command_dependency = true;
+				break;
+			case exclam_char:
+				used->ignore_command_dependency = false;
+				break;
+			case equal_char:
+				used->assign = true;
+				break;
+			case hyphen_char:
+				used->ignore_error = true;
+				break;
+			case at_char:
+				if (!do_not_exec_rule) {
+					used->silent = true;
+				}
+				break;
+			case plus_char:
+				if(posix) {
+				  used->always_exec  = true;
+				}
+				break;
+			}
+		}
+		/* If all command lines of the template are prefixed with "?"*/
+		/* the VIRTUAL_ROOT is not used for cmd consistency checks */
+		if (!used->ignore_command_dependency) {
+			ignore_all_command_dependency = false;
+		}
+		/* Internalize the expanded and stripped command line */
+		new_command_line = GETNAME(start, FIND_LENGTH);
+		if ((used->command_line == NULL) &&
+		    (line->body.line.sccs_command)) {
+			used->command_line = new_command_line;
+			new_command_longer = false;
+		}
+		/* Compare it with the old one for command consistency */
+		if (used->command_line != new_command_line) {
+			Name vpath_translated = vpath_translation(new_command_line);
+			if (keep_state &&
+			    !used->ignore_command_dependency && (vpath_translated != used->command_line)) {
+				if (debug_level > 0) {
+					if (used->command_line != NULL
+					    && *used->command_line->string_mb !=
+					    '\0') {
+						(void) printf(catgets(catd, 1, 32, "%*sBuilding %s because new command \n\t%s\n%*sdifferent from old\n\t%s\n"),
+							      recursion_level,
+							      "",
+							      target->string_mb,
+							      vpath_translated->string_mb,
+							      recursion_level,
+							      "",
+							      used->
+							      command_line->
+							      string_mb);
+					} else {
+						(void) printf(catgets(catd, 1, 33, "%*sBuilding %s because new command \n\t%s\n%*sdifferent from empty old command\n"),
+							      recursion_level,
+							      "",
+							      target->string_mb,
+							      vpath_translated->string_mb,
+							      recursion_level,
+							      "");
+					}
+				}
+				command_changed = true;
+                                line->body.line.is_out_of_date = true;
+			}
+			used->command_line = new_command_line;
+		}
+		if (command_line.free_after_use) {
+			retmem(command_line.buffer.start);
+		}
+	}
+	/* Check if the old command is longer than the new for */
+	/* command consistency */
+	if (used != NULL) {
+		*insert = NULL;
+		if (keep_state &&
+		    !ignore_all_command_dependency) {
+			if (debug_level > 0) {
+				(void) printf(catgets(catd, 1, 34, "%*sBuilding %s because new command shorter than old\n"),
+					      recursion_level,
+					      "",
+					      target->string_mb);
+			}
+			command_changed = true;
+                        line->body.line.is_out_of_date = true;
+		}
+	}
+	/* Check if the new command is longer than the old command for */
+	/* command consistency */
+	if (new_command_longer &&
+	    !ignore_all_command_dependency &&
+	    keep_state) {
+		if (debug_level > 0) {
+			(void) printf(catgets(catd, 1, 35, "%*sBuilding %s because new command longer than old\n"),
+				      recursion_level,
+				      "",
+				      target->string_mb);
+		}
+		command_changed = true;
+                line->body.line.is_out_of_date = true;
+	}
+	/* Unbind the magic macros */
+	(void) SETVAR(c_at, (Name) NULL, false);
+	(void) SETVAR(star, (Name) NULL, false);
+	(void) SETVAR(less_name, (Name) NULL, false);
+	(void) SETVAR(percent_name, (Name) NULL, false);
+	(void) SETVAR(query, (Name) NULL, false);
+        if (query_list != NULL) {
+        	delete_query_chain(query_list);
+        }
+	(void) SETVAR(hat, (Name) NULL, false);
+        if (hat_list != NULL) {
+        	delete_query_chain(hat_list);
+        }
+
+	if (conditional_macro_used) {
+		target->conditional_macro_list = cond_macro_list;
+		cond_macro_list = NULL;
+		target->depends_on_conditional = true;
+	}
+}
+
+/*
+ *	touch_command(line, target, result)
+ *
+ *	If this is an "make -t" run we do this.
+ *	We touch all targets in the target group ("foo + fie:") if any.
+ *
+ *	Return value:
+ *				Indicates if the command failed or not
+ *
+ *	Parameters:
+ *		line		The command line to update
+ *		target		The target we are touching
+ *		result		Initial value for the result we return
+ *
+ *	Global variables used:
+ *		do_not_exec_rule Indicates that -n is on
+ *		silent		Do not echo commands
+ */
+static Doname
+touch_command(register Property line, register Name target, Doname result)
+{
+	Name			name;
+	register Chain		target_group;
+	String_rec		touch_string;
+	wchar_t			buffer[MAXPATHLEN];
+	Name			touch_cmd;
+	Cmd_line		rule;
+
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+	Avo_MToolJobResultMsg	*job_result_msg;
+	RWCollectable		*xdr_msg;
+	int			child_pid = 0;
+	wchar_t			string[MAXPATHLEN];
+	char			mbstring[MAXPATHLEN];
+	int			filed;
+#endif
+
+	SEND_MTOOL_MSG(
+		if (!sent_rsrc_info_msg) {
+			if (userName[0] == '\0') {
+				avo_get_user(userName, NULL);
+			}
+			if (hostName[0] == '\0') {
+				strcpy(hostName, avo_hostname());
+			}
+			send_rsrc_info_msg(1, hostName, userName);
+			sent_rsrc_info_msg = 1;
+		}
+		send_job_start_msg(line);
+		job_result_msg = new Avo_MToolJobResultMsg();
+	);
+	for (name = target, target_group = NULL; name != NULL;) {
+		if (!name->is_member) {
+			/*
+			 * Build a touch command that can be passed
+			 * to dosys(). If KEEP_STATE is on, "make -t"
+			 * will save the proper command, not the
+			 * "touch" in .make.state.
+			 */
+			INIT_STRING_FROM_STACK(touch_string, buffer);
+			MBSTOWCS(wcs_buffer, NOCATGETS("touch "));
+			append_string(wcs_buffer, &touch_string, FIND_LENGTH);
+			touch_cmd = name;
+			if (name->has_vpath_alias_prop) {
+				touch_cmd = get_prop(name->prop,
+						 vpath_alias_prop)->
+						   body.vpath_alias.alias;
+			}
+			APPEND_NAME(touch_cmd,
+				      &touch_string,
+				      FIND_LENGTH);
+			touch_cmd = GETNAME(touch_string.buffer.start,
+					    FIND_LENGTH);
+			if (touch_string.free_after_use) {
+				retmem(touch_string.buffer.start);
+			}
+			if (!silent ||
+			    do_not_exec_rule &&
+			    (target_group == NULL)) {
+				(void) printf("%s\n", touch_cmd->string_mb);
+				SEND_MTOOL_MSG(
+					job_result_msg->appendOutput(AVO_STRDUP(touch_cmd->string_mb));
+				);
+			}
+			/* Run the touch command, or simulate it */
+			if (!do_not_exec_rule) {
+
+				SEND_MTOOL_MSG(
+					(void) sprintf(mbstring,
+							NOCATGETS("%s/make.stdout.%d.%d.XXXXXX"),
+							tmpdir,
+							getpid(),
+							file_number++);
+				
+					int tmp_fd = mkstemp(mbstring);
+					if(tmp_fd) {
+						(void) close(tmp_fd);
+					}
+
+					stdout_file = strdup(mbstring);
+					stderr_file = NULL;
+					child_pid = pollResults(stdout_file,
+								(char *)NULL,
+								(char *)NULL);
+				);
+
+				result = dosys(touch_cmd,
+					       false,
+					       false,
+					       false,
+					       false,
+					       name,
+					       send_mtool_msgs);
+
+				SEND_MTOOL_MSG(
+					append_job_result_msg(job_result_msg);
+					if (child_pid > 0) {
+						kill(child_pid, SIGUSR1);
+						while (!((waitpid(child_pid, 0, 0) == -1)
+							&& (errno == ECHILD)));
+					}
+					child_pid = 0;
+					(void) unlink(stdout_file);
+					retmem_mb(stdout_file);
+					stdout_file = NULL;
+				);
+
+			} else {
+				result = build_ok;
+			}
+		} else {
+			result = build_ok;
+		}
+		if (target_group == NULL) {
+			target_group = line->body.line.target_group;
+		} else {
+			target_group = target_group->next;
+		}
+		if (target_group != NULL) {
+			name = target_group->name;
+		} else {
+			name = NULL;
+		}
+	}
+	SEND_MTOOL_MSG(
+		job_result_msg->setResult(job_msg_id, (result == build_ok) ? 0 : 1, DONE);
+		xdr_msg = (RWCollectable*) job_result_msg;
+		xdr(&xdrs, xdr_msg);
+		(void) fflush(mtool_msgs_fp);
+		delete job_result_msg;
+	);
+	return result;
+}
+
+/*
+ *	update_target(line, result)
+ *
+ *	updates the status of a target after executing its commands.
+ *
+ *	Parameters:
+ *		line		The command line block to update
+ *		result		Indicates that build is OK so can update
+ *
+ *	Global variables used:
+ *		do_not_exec_rule Indicates that -n is on
+ *		touch		Fake the new timestamp if we are just touching
+ */
+void
+update_target(Property line, Doname result)
+{
+	Name			target;
+	Chain			target_group;
+	Property		line2;
+	timestruc_t		old_stat_time;
+	Property		member;
+
+	/*
+	 * [tolik] Additional fix for bug 1063790. It was fixed
+	 * for serial make long ago, but DMake dumps core when
+	 * target is a symlink and sccs file is newer then target. 
+	 * In this case, finish_children() calls update_target()
+	 * with line==NULL.
+	 */
+	if(line == NULL) {
+		/* XXX. Should we do anything here? */
+		return;
+	}	
+
+	target = line->body.line.target;
+
+	if ((result == build_ok) && (line->body.line.command_used != NULL)) {
+		if (do_not_exec_rule ||
+		    touch ||
+		    (target->is_member &&
+		     (line->body.line.command_template != NULL) &&
+		     (line->body.line.command_template->command_line->string_mb[0] == 0) &&
+		     (line->body.line.command_template->next == NULL))) {
+			/* If we are simulating execution we need to fake a */
+			/* new timestamp for the target we didnt build */
+			target->stat.time = file_max_time;
+		} else {
+			/*
+			 * If we really built the target we read the new
+			 * timestamp.
+			 * Fix for bug #1110906: if .c file is newer than
+			 * the corresponding .o file which is in an archive
+			 * file, make will compile the .c file but it won't
+			 * update the object in the .a file.
+			 */
+			old_stat_time = target->stat.time;
+			target->stat.time = file_no_time;
+			(void) exists(target);
+			if ((target->is_member) &&
+			    (target->stat.time == old_stat_time)) {
+				member = get_prop(target->prop, member_prop);
+				if (member != NULL) {
+					target->stat.time = member->body.member.library->stat.time;
+					target->stat.time.tv_sec++;
+				}
+			}
+		}
+		/* If the target is part of a group we need to propagate the */
+		/* result of the run to all members */
+		for (target_group = line->body.line.target_group;
+		     target_group != NULL;
+		     target_group = target_group->next) {
+			target_group->name->stat.time = target->stat.time;
+			line2 = maybe_append_prop(target_group->name,
+						  line_prop);
+			line2->body.line.command_used =
+			  line->body.line.command_used;
+			line2->body.line.target = target_group->name;
+		}
+	}
+	target->has_built = true;
+}
+
+/*
+ *	sccs_get(target, command)
+ *
+ *	Figures out if it possible to sccs get a file
+ *	and builds the command to do it if it is.
+ *
+ *	Return value:
+ *				Indicates if sccs get failed or not
+ *
+ *	Parameters:
+ *		target		Target to get
+ *		command		Where to deposit command to use
+ *
+ *	Global variables used:
+ *		debug_level	Should we trace activities?
+ *		recursion_level	Used for tracing
+ *		sccs_get_rule	The rule to used for sccs getting
+ */
+static Doname
+sccs_get(register Name target, register Property *command)
+{
+	register int		result;
+	char			link[MAXPATHLEN];
+	String_rec		string;
+	wchar_t			name[MAXPATHLEN];
+	register wchar_t	*p;
+	timestruc_t		sccs_time;
+	register Property	line;
+	int			sym_link_depth = 0;
+
+	/* For sccs, we need to chase symlinks. */
+        while (target->stat.is_sym_link) {
+		if (sym_link_depth++ > 90) {
+			fatal(catgets(catd, 1, 95, "Can't read symbolic link `%s': Number of symbolic links encountered during path name traversal exceeds 90."),
+			      target->string_mb);
+		}
+                /* Read the value of the link. */
+                result = readlink_vroot(target->string_mb,
+					link,
+					sizeof(link),
+					NULL,
+					VROOT_DEFAULT);
+                if (result == -1) {
+                        fatal(catgets(catd, 1, 36, "Can't read symbolic link `%s': %s"),
+                              target->string_mb, errmsg(errno));
+		}
+		link[result] = 0;
+                /* Use the value to build the proper filename. */
+                INIT_STRING_FROM_STACK(string, name);
+
+		Wstring wcb(target);
+                if ((link[0] != slash_char) &&
+                    ((p = (wchar_t *) wsrchr(wcb.get_string(), slash_char)) != NULL)) {
+                        append_string(wcb.get_string(), &string, p - wcb.get_string() + 1);
+		}
+                append_string(link, &string, result);
+                /* Replace the old name with the translated name. */
+		target = normalize_name(string.buffer.start, string.text.p - string.buffer.start);
+                (void) exists(target);
+                if (string.free_after_use) {
+                        retmem(string.buffer.start);
+		}
+        }
+
+	/*
+	 * read_dir() also reads the ?/SCCS dir and saves information
+	 * about which files have SCSC/s. files.
+	 */
+	if (target->stat.has_sccs == DONT_KNOW_SCCS) {
+		read_directory_of_file(target);
+	}
+	switch (target->stat.has_sccs) {
+	case DONT_KNOW_SCCS:
+		/* We dont know by now there is no SCCS/s.* */
+		target->stat.has_sccs = NO_SCCS;
+	case NO_SCCS:
+		/*
+		 * If there is no SCCS/s.* but the plain file exists,
+		 * we say things are OK.
+		 */
+		if (target->stat.time > file_doesnt_exist) {
+			return build_ok;
+		}
+		/* If we cant find the plain file, we give up. */
+		return build_dont_know;
+	case HAS_SCCS:
+		/*
+		 * Pay dirt. We now need to figure out if the plain file
+		 * is out of date relative to the SCCS/s.* file.
+		 */
+		sccs_time = exists(get_prop(target->prop,
+					    sccs_prop)->body.sccs.file);
+		break;
+	}
+
+	if ((!target->has_complained &&
+	    (sccs_time != file_doesnt_exist) &&
+	    (sccs_get_rule != NULL))) {
+		/* only checking */
+		if (command == NULL) {
+			return build_ok;
+		}
+		/*
+		 * We provide a command line for the target. The line is a
+		 * "sccs get" command from default.mk.
+		 */
+		line = maybe_append_prop(target, line_prop);
+		*command = line;
+		if (sccs_time > target->stat.time) {
+			/*
+			 * And only if the plain file is out of date do we
+			 * request execution of the command.
+			 */
+			line->body.line.is_out_of_date = true;
+			if (debug_level > 0) {
+				(void) printf(catgets(catd, 1, 37, "%*sSccs getting %s because s. file is younger than source file\n"),
+					      recursion_level,
+					      "",
+					      target->string_mb);
+			}
+		}
+		line->body.line.sccs_command = true;
+		line->body.line.command_template = sccs_get_rule;
+		if(!svr4 && (!allrules_read || posix)) {
+		   if((target->prop) &&
+		      (target->prop->body.sccs.file) &&
+		      (target->prop->body.sccs.file->string_mb)) {
+		      if((strlen(target->prop->body.sccs.file->string_mb) ==
+			strlen(target->string_mb) + 2) && 
+		        (target->prop->body.sccs.file->string_mb[0] == 's') &&
+		        (target->prop->body.sccs.file->string_mb[1] == '.')) {
+
+		         line->body.line.command_template = get_posix_rule;
+		      }
+		   }
+		}
+		line->body.line.target = target;
+		/*
+		 * Also make sure the rule is build with $* and $<
+		 * bound properly.
+		 */
+		line->body.line.star = NULL;
+		line->body.line.less = NULL;
+		line->body.line.percent = NULL;
+		return build_ok;
+	}
+	return build_dont_know;
+}
+
+/*
+ *	read_directory_of_file(file)
+ *
+ *	Reads the directory the specified file lives in.
+ *
+ *	Parameters:
+ *		file		The file we need to read dir for
+ *
+ *	Global variables used:
+ *		dot		The Name ".", used as the default dir
+ */
+void
+read_directory_of_file(register Name file)
+{
+
+	Wstring file_string(file);
+	wchar_t * wcb = file_string.get_string();
+	wchar_t usr_include_buf[MAXPATHLEN];
+	wchar_t usr_include_sys_buf[MAXPATHLEN];
+
+	register Name		directory = dot;
+	register wchar_t	*p = (wchar_t *) wsrchr(wcb,
+							(int) slash_char);
+	register int		length = p - wcb;
+	static Name		usr_include;
+	static Name		usr_include_sys;
+
+	if (usr_include == NULL) {
+		MBSTOWCS(usr_include_buf, NOCATGETS("/usr/include"));
+		usr_include = GETNAME(usr_include_buf, FIND_LENGTH);
+		MBSTOWCS(usr_include_sys_buf, NOCATGETS("/usr/include/sys"));
+		usr_include_sys = GETNAME(usr_include_sys_buf, FIND_LENGTH);
+	}
+
+	/*
+	 * If the filename contains a "/" we have to extract the path
+	 * Else the path defaults to ".".
+	 */
+	if (p != NULL) {
+		/*
+		 * Check some popular directories first to possibly
+		 * save time. Compare string length first to gain speed.
+		 */
+		if ((usr_include->hash.length == length) &&
+		    IS_WEQUALN(usr_include_buf,
+			       wcb,
+			       length)) {
+			directory = usr_include;
+		} else if ((usr_include_sys->hash.length == length) &&
+		           IS_WEQUALN(usr_include_sys_buf,
+		                      wcb,
+		                      length)) {
+			directory = usr_include_sys;
+		} else {
+			directory = GETNAME(wcb, length);
+		}
+	}
+	(void) read_dir(directory,
+			(wchar_t *) NULL,
+			(Property) NULL,
+			(wchar_t *) NULL);
+}
+
+/*
+ *	add_pattern_conditionals(target)
+ *
+ *	Scan the list of conditionals defined for pattern targets and add any
+ *	that match this target to its list of conditionals.
+ *
+ *	Parameters:
+ *		target		The target we should add conditionals for
+ *
+ *	Global variables used:
+ *		conditionals	The list of pattern conditionals
+ */
+static void
+add_pattern_conditionals(register Name target)
+{
+	register Property	conditional;
+	Property		new_prop;
+	Property		*previous;
+	Name_rec		dummy;
+	wchar_t			*pattern;
+	wchar_t			*percent;
+	int			length;
+
+	Wstring wcb(target);
+	Wstring wcb1;
+
+	for (conditional = get_prop(conditionals->prop, conditional_prop);
+	     conditional != NULL;
+	     conditional = get_prop(conditional->next, conditional_prop)) {
+		wcb1.init(conditional->body.conditional.target);
+		pattern = wcb1.get_string();
+		if (pattern[1] != 0) {
+			percent = (wchar_t *) wschr(pattern, (int) percent_char);
+			if (!wcb.equaln(pattern, percent-pattern) ||
+			    !IS_WEQUAL(wcb.get_string(wcb.length()-wslen(percent+1)), percent+1)) {
+				continue;
+			}
+		}
+		for (previous = &target->prop;
+		     *previous != NULL;
+		     previous = &(*previous)->next) {
+			if (((*previous)->type == conditional_prop) &&
+			    ((*previous)->body.conditional.sequence >
+			     conditional->body.conditional.sequence)) {
+				break;
+			}
+		}
+		if (*previous == NULL) {
+			new_prop = append_prop(target, conditional_prop);
+		} else {
+			dummy.prop = NULL;
+			new_prop = append_prop(&dummy, conditional_prop);
+			new_prop->next = *previous;
+			*previous = new_prop;
+		}
+		target->conditional_cnt++;
+		new_prop->body.conditional = conditional->body.conditional;
+	}
+}
+
+/*
+ *	set_locals(target, old_locals)
+ *
+ *	Sets any conditional macros for the target.
+ *	Each target carries a possibly empty set of conditional properties.
+ *
+ *	Parameters:
+ *		target		The target to set conditional macros for
+ *		old_locals	Space to store old values in
+ *
+ *	Global variables used:
+ *		debug_level	Should we trace activity?
+ *		is_conditional	We need to preserve this value
+ *		recursion_level	Used for tracing
+ */
+void
+set_locals(register Name target, register Property old_locals)
+{
+	register Property	conditional;
+	register int		i;
+	register Boolean	saved_conditional_macro_used;
+	Chain			cond_name;
+	Chain			cond_chain;
+
+#ifdef DISTRIBUTED
+	if (target->dont_activate_cond_values) {
+		return;
+	}
+#endif
+
+	saved_conditional_macro_used = conditional_macro_used;
+
+	/* Scan the list of conditional properties and apply each one */
+	for (conditional = get_prop(target->prop, conditional_prop), i = 0;
+	     conditional != NULL;
+	     conditional = get_prop(conditional->next, conditional_prop),
+	     i++) {
+		/* Save the old value */
+		old_locals[i].body.macro =
+		  maybe_append_prop(conditional->body.conditional.name,
+				    macro_prop)->body.macro;
+		if (debug_level > 1) {
+			(void) printf(catgets(catd, 1, 38, "%*sActivating conditional value: "),
+				      recursion_level,
+				      "");
+		}
+		/* Set the conditional value. Macros are expanded when the */
+		/* macro is refd as usual */
+		if ((conditional->body.conditional.name != virtual_root) ||
+		    (conditional->body.conditional.value != virtual_root)) {
+			(void) SETVAR(conditional->body.conditional.name,
+				      conditional->body.conditional.value,
+				      (Boolean) conditional->body.conditional.append);
+		}
+		cond_name = ALLOC(Chain);
+		cond_name->name = conditional->body.conditional.name;
+	}
+	/* Put this target on the front of the chain of conditional targets */
+	cond_chain = ALLOC(Chain);
+	cond_chain->name = target;
+	cond_chain->next = conditional_targets;
+	conditional_targets = cond_chain;
+	conditional_macro_used = saved_conditional_macro_used;
+}
+
+/*
+ *	reset_locals(target, old_locals, conditional, index)
+ *
+ *	Removes any conditional macros for the target.
+ *
+ *	Parameters:
+ *		target		The target we are retoring values for
+ *		old_locals	The values to restore
+ *		conditional	The first conditional block for the target
+ *		index		into the old_locals vector
+ *	Global variables used:
+ *		debug_level	Should we trace activities?
+ *		recursion_level	Used for tracing
+ */
+void
+reset_locals(register Name target, register Property old_locals, register Property conditional, register int index)
+{
+	register Property	this_conditional;
+	Chain			cond_chain;
+
+#ifdef DISTRIBUTED
+	if (target->dont_activate_cond_values) {
+		return;
+	}
+#endif
+
+	/* Scan the list of conditional properties and restore the old value */
+	/* to each one Reverse the order relative to when we assigned macros */
+	this_conditional = get_prop(conditional->next, conditional_prop);
+	if (this_conditional != NULL) {
+		reset_locals(target, old_locals, this_conditional, index+1);
+	} else {
+		/* Remove conditional target from chain */
+		if (conditional_targets == NULL ||
+		    conditional_targets->name != target) {
+			warning(catgets(catd, 1, 39, "Internal error: reset target not at head of condtional_targets chain"));
+		} else {
+			cond_chain = conditional_targets->next;
+			retmem_mb((caddr_t) conditional_targets);
+			conditional_targets = cond_chain;
+		}
+	}
+	get_prop(conditional->body.conditional.name->prop,
+		 macro_prop)->body.macro = old_locals[index].body.macro;
+	if (conditional->body.conditional.name == virtual_root) {
+		(void) SETVAR(virtual_root, getvar(virtual_root), false);
+	}
+	if (debug_level > 1) {
+		if (old_locals[index].body.macro.value != NULL) {
+			(void) printf(catgets(catd, 1, 40, "%*sdeactivating conditional value: %s= %s\n"),
+				      recursion_level,
+				      "",
+				      conditional->body.conditional.name->
+				      string_mb,
+				      old_locals[index].body.macro.value->
+				      string_mb);
+		} else {
+			(void) printf(catgets(catd, 1, 41, "%*sdeactivating conditional value: %s =\n"),
+				      recursion_level,
+				      "",
+				      conditional->body.conditional.name->
+				      string_mb);
+		}
+	}
+}
+
+/*
+ *	check_auto_dependencies(target, auto_count, automatics)
+ *
+ *	Returns true if the target now has a dependency
+ *	it didn't previously have (saved on automatics).
+ *
+ *	Return value:
+ *				true if new dependency found
+ *
+ *	Parameters:
+ *		target		Target we check
+ *		auto_count	Number of old automatic vars
+ *		automatics	Saved old automatics
+ *
+ *	Global variables used:
+ *		keep_state	Indicates that .KEEP_STATE is on
+ */
+Boolean
+check_auto_dependencies(Name target, int auto_count, Name *automatics)
+{
+	Name		*p;
+	int		n;
+	Property	line;
+	Dependency	dependency;
+
+	if (keep_state) {
+		if ((line = get_prop(target->prop, line_prop)) == NULL) {
+			return false;
+		}
+		/* Go thru new list of automatic depes */
+		for (dependency = line->body.line.dependencies;
+		     dependency != NULL;
+		     dependency = dependency->next) {
+			/* And make sure that each one existed before we */
+			/* built the target */
+			if (dependency->automatic && !dependency->stale) {
+				for (n = auto_count, p = automatics;
+				     n > 0;
+				     n--) {
+					if (*p++ == dependency->name) {
+						/* If we can find it on the */
+						/* saved list of autos we */
+						/* are OK  */
+						goto not_new;
+					}
+				}
+				/* But if we scan over the old list */
+				/* of auto. without finding it it is */
+				/* new and we must check it */
+				return true;
+			}
+		not_new:;
+		}
+		return false;
+	} else {
+		return false;
+	}
+}
+
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+void
+create_xdrs_ptr(void)
+{
+	static int	xdrs_init = 0;
+
+	if (!xdrs_init) {
+		xdrs_init = 1;
+		mtool_msgs_fp = fdopen(mtool_msgs_fd, "a");
+		xdrstdio_create(&xdrs,
+		                mtool_msgs_fp,
+		                XDR_ENCODE);
+	}
+}
+
+XDR *
+get_xdrs_ptr(void)
+{
+	return &xdrs;
+}
+
+FILE *
+get_mtool_msgs_fp(void)
+{
+	return mtool_msgs_fp;
+}
+
+int
+get_job_msg_id(void)
+{
+	return job_msg_id;
+}
+
+// Continuously poll and show the results of remotely executing a job,
+// i.e., output the stdout and stderr files.
+
+static int
+pollResults(char *outFn, char *errFn, char *hostNm)
+{
+	int		child;
+
+	child = fork();
+	switch (child) {
+	case -1:
+		break;
+	case 0:
+		enable_interrupt((void (*) (int))SIG_DFL);
+#ifdef linux
+		(void) signal(SIGUSR1, Avo_PollResultsAction_Sigusr1Handler);
+#else
+		(void) sigset(SIGUSR1, Avo_PollResultsAction_Sigusr1Handler);
+#endif
+		pollResultsAction(outFn, errFn);
+
+		exit(0);
+		break;
+	default:
+		break;
+	}
+	return child;
+}
+
+// This is the PollResultsAction SIGUSR1 handler.
+
+static bool_t pollResultsActionTimeToFinish = FALSE;
+
+extern "C" void
+Avo_PollResultsAction_Sigusr1Handler(int foo)
+{
+	pollResultsActionTimeToFinish = TRUE;
+}
+
+static void
+pollResultsAction(char *outFn, char *errFn)
+{
+	int			fd;
+	time_t			file_time = 0;
+	long			file_time_nsec = 0;
+	struct stat		statbuf;
+	int			stat_rc;
+
+	// Keep stat'ing until file exists.
+	while (((stat_rc = stat(outFn, &statbuf)) != 0) &&
+	       (errno == ENOENT) && 
+	       !pollResultsActionTimeToFinish) {
+		us_sleep(STAT_RETRY_SLEEP_TIME);
+	}
+	// The previous stat() could be failed due to EINTR
+	// So one more try is needed
+	if (stat_rc != 0 && stat(outFn, &statbuf) != 0) {
+		// stat() failed
+		warning(NOCATGETS("Internal error: stat(\"%s\", ...) failed: %s\n"),
+			outFn, strerror(errno));
+		exit(1);
+	}
+
+	if ((fd = open(outFn, O_RDONLY)) < 0
+		&& (errno != EINTR || (fd = open(outFn, O_RDONLY)) < 0)) {
+		// open() failed
+		warning(NOCATGETS("Internal error: open(\"%s\", O_RDONLY) failed: %s\n"),
+			outFn, strerror(errno));
+		exit(1);
+	}
+
+	while (!pollResultsActionTimeToFinish && stat(outFn, &statbuf) == 0) {
+#ifdef linux
+		if ((statbuf.st_mtime > file_time)
+		   ) {
+			file_time = statbuf.st_mtime;
+			rxmGetNextResultsBlock(fd);
+		}
+#else
+		if ((statbuf.st_mtim.tv_sec > file_time) ||
+		    ((statbuf.st_mtim.tv_sec == file_time) &&
+		    (statbuf.st_mtim.tv_nsec > file_time_nsec))
+		   ) {
+			file_time = statbuf.st_mtim.tv_sec;
+			file_time_nsec = statbuf.st_mtim.tv_nsec;
+			rxmGetNextResultsBlock(fd);
+		}
+#endif
+		us_sleep(STAT_RETRY_SLEEP_TIME);
+	}
+	// Check for the rest of output
+	rxmGetNextResultsBlock(fd);
+
+	(void) close(fd);
+}
+
+static void
+rxmGetNextResultsBlock(int fd)
+{
+	size_t			to_read = 8 * 1024;
+	ssize_t			bytes_read;
+	ssize_t			bytes_written;
+	char			results_buf[8 * 1024];
+	sigset_t		newset;
+	sigset_t		oldset;
+
+	// Read some more from the output/results file.
+	// Hopefully the kernel managed to prefetch the stuff.
+	bytes_read = read(fd, results_buf, to_read);
+	while (bytes_read > 0) {
+		AVO_BLOCK_INTERUPTS;
+		bytes_written = write(1, results_buf, bytes_read);
+		AVO_UNBLOCK_INTERUPTS;
+		if (bytes_written != bytes_read) {
+			// write() failed
+			warning(NOCATGETS("Internal error: write(1, ...) failed: %s\n"),
+				strerror(errno));
+			exit(1);
+		}
+		bytes_read = read(fd, results_buf, to_read);
+	}
+}
+
+// Generic, interruptable microsecond resolution sleep member function.
+
+static int
+us_sleep(unsigned int nusecs)
+{
+	struct pollfd dummy;
+	int timeout;
+
+	if ((timeout = nusecs/1000) <= 0) {
+		timeout = 1;
+	}
+	return poll(&dummy, 0, timeout);
+}
+#endif /* TEAMWARE_MAKE_CMN */
+
+// Recursively delete each of the Chain struct on the chain.
+
+static void
+delete_query_chain(Chain ch)
+{
+	if (ch == NULL) {
+		return;
+	} else {
+		delete_query_chain(ch->next);
+		retmem_mb((char *) ch);
+	}
+}
+
+Doname
+target_can_be_built(register Name target) {
+	Doname		result = build_dont_know;
+	Name		true_target = target;
+	Property	line;
+
+	if (target == wait_name) {
+		return(build_ok);
+	}
+	/*
+	 * If the target is a constructed one for a "::" target,
+	 * we need to consider that.
+	 */
+	if (target->has_target_prop) {
+		true_target = get_prop(target->prop,
+				       target_prop)->body.target.target;
+	}
+
+	(void) exists(true_target);
+
+	if (true_target->state == build_running) {
+		return(build_running);
+	}
+	if (true_target->stat.time != file_doesnt_exist) {
+		result = build_ok;
+	}
+
+	/* get line property for the target */
+	line = get_prop(true_target->prop, line_prop);
+
+	/* first check for explicit rule */
+	if (line != NULL && line->body.line.command_template != NULL) {
+		result = build_ok;
+	}
+	/* try to find pattern rule */
+	if (result == build_dont_know) {
+		result = find_percent_rule(target, NULL, false);
+	}
+	
+	/* try to find double suffix rule */
+	if (result == build_dont_know) {
+		if (target->is_member) {
+			Property member = get_prop(target->prop, member_prop);
+			if (member != NULL && member->body.member.member != NULL) {
+				result = find_ar_suffix_rule(target, member->body.member.member, NULL, false);
+			} else {
+				result = find_double_suffix_rule(target, NULL, false);
+			}
+		} else {
+			result = find_double_suffix_rule(target, NULL, false);
+		}
+	}
+	
+	/* try to find suffix rule */
+	if ((result == build_dont_know) && second_pass) {
+		result = find_suffix_rule(target, target, empty_name, NULL, false);
+	}
+	
+	/* check for sccs */
+	if (result == build_dont_know) {
+		result = sccs_get(target, NULL);
+	}
+	
+	/* try to find dyn target */
+	if (result == build_dont_know) {
+		Name dtarg = find_dyntarget(target);
+		if (dtarg != NULL) {
+			result = target_can_be_built(dtarg);
+		}
+	}
+	
+	/* check whether target was mentioned in makefile */
+	if (result == build_dont_know) {
+		if (target->colons != no_colon) {
+			result = build_ok;
+		}
+	}
+
+	/* result */
+	return result;
+}
