--- /dev/null	2015-05-20 11:04:05.000000000 -0400
+++ new/usr/src/cmd/make/Makefile	2015-05-20 11:04:05.780719058 -0400
@@ -0,0 +1,34 @@
+#
+# 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 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.21 06/12/12
+#
+
+TOP 	= ..
+
+SUBDIRS= 	lib \
+		bin \
+		localize \
+		man
+
+include ${TOP}/rules/recurse.mk
--- /dev/null	2015-05-20 11:04:06.000000000 -0400
+++ new/usr/src/cmd/make/bin/Makefile	2015-05-20 11:04:06.087853770 -0400
@@ -0,0 +1,32 @@
+#
+# 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 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.16 06/12/12
+#
+
+TOP =		../..
+
+# SUBDIRS =	make maketool rxm rxs
+SUBDIRS =	make  rxm rxs
+
+include $(TOP)/rules/recurse.mk
--- /dev/null	2015-05-20 11:04:06.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/Common.mk	2015-05-20 11:04:06.292586625 -0400
@@ -0,0 +1,46 @@
+#
+# 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 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Common.mk 1.3 06/12/12
+#
+
+TOP		= ../../../../..
+include $(TOP)/rules/master.mk
+
+PKG_TOP		= $(TOP)/Make
+
+LIBBSD_DIR	= $(PKG_TOP)/libbsd
+LIBBSD		= $(LIBBSD_DIR)/$(VARIANT)/libbsd.a
+
+LIBMKSDMSI18N_DIR = $(PKG_TOP)/libmksdmsi18n
+LIBMKSDMSI18N	= $(LIBMKSDMSI18N_DIR)/$(VARIANT)/libmksdmsi18n.a
+
+LIBMKSH_DIR	= $(PKG_TOP)/libmksh
+LIBMKSH		= $(LIBMKSH_DIR)/$(VARIANT)/libmksh.a
+
+LIBVROOT_DIR	= $(PKG_TOP)/libvroot
+LIBVROOT	= $(LIBVROOT_DIR)/$(VARIANT)/libvroot.a
+
+SRC		= ../src
+include $(TOP)/rules/derived.mk
+
--- /dev/null	2015-05-20 11:04:06.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/Makefile	2015-05-20 11:04:06.479645523 -0400
@@ -0,0 +1,32 @@
+#
+# 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 1997 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.7 06/12/12
+#
+
+TOP =			../../..
+
+#SUBDIRS =		dmake localize
+SUBDIRS =		smake make.xpg4 make.svr4
+
+include $(TOP)/rules/recurse.mk
--- /dev/null	2015-05-20 11:04:06.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/common/ar.cc	2015-05-20 11:04:06.669732341 -0400
@@ -0,0 +1,908 @@
+/*
+ * 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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)ar.cc 1.28 06/12/12
+ */
+
+#pragma	ident	"@(#)ar.cc	1.28	06/12/12"
+
+/*
+ *	ar.c
+ *
+ *	Deal with the lib.a(member.o) and lib.a((entry-point)) notations
+ *
+ * Look inside archives for notations a(b) and a((b))
+ *	a(b)	is file member   b  in archive a
+ *	a((b))	is entry point   b  in object archive a
+ *
+ * For 6.0, create a make which can understand all archive
+ * formats.  This is kind of tricky, and <ar.h> isnt any help.
+ */
+
+/*
+ * Included files
+ */
+#include <avo/avo_alloca.h>		/* alloca() */
+#include <ar.h>
+#include <errno.h>		/* errno */
+#include <fcntl.h>		/* open() */
+#include <mk/defs.h>
+#include <mksh/misc.h>		/* retmem_mb() */
+
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+struct ranlib {
+	union {
+		off_t	ran_strx;	/* string table index of */
+		char	*ran_name;	/* symbol defined by */
+	}	ran_un;
+	off_t	ran_off;		/* library member at this offset */
+};
+#else
+#include <ranlib.h>
+#endif
+
+#if defined(linux)
+#include <ctype.h>		/* isspace */
+#else
+#include <unistd.h>		/* close() */
+#endif
+
+
+/*
+ * Defined macros
+ */
+#ifndef S5EMUL
+#undef BITSPERBYTE
+#define BITSPERBYTE	8
+#endif
+
+/*
+ * Defines for all the different archive formats.  See next comment
+ * block for justification for not using <ar.h>s versions.
+ */
+#define AR_5_MAGIC		"<ar>"		/* 5.0 format magic string */
+#define AR_5_MAGIC_LENGTH	4		/* 5.0 format string length */
+
+#define AR_PORT_MAGIC		"!<arch>\n"	/* Port. (6.0) magic string */
+#define AR_PORT_MAGIC_LENGTH	8		/* Port. (6.0) string length */
+#define AR_PORT_END_MAGIC	"`\n"		/* Port. (6.0) end of header */
+#define AR_PORT_WORD		4		/* Port. (6.0) 'word' length */
+
+/*
+ * typedefs & structs
+ */
+/*
+ * These are the archive file headers for the formats.  Note
+ * that it really doesnt matter if these structures are defined
+ * here.  They are correct as of the respective archive format
+ * releases.  If the archive format is changed, then since backwards
+ * compatability is the desired behavior, a new structure is added
+ * to the list.
+ */
+typedef struct {	/* 5.0 ar header format: vax family; 3b family */
+	char			ar_magic[AR_5_MAGIC_LENGTH];	/* AR_5_MAGIC*/
+	char			ar_name[16];	/* Space terminated */
+	char			ar_date[AR_PORT_WORD];	/* sgetl() accessed */
+	char			ar_syms[AR_PORT_WORD];	/* sgetl() accessed */
+}			Arh_5;
+
+typedef struct {	/* 5.0 ar symbol format: vax family; 3b family */
+	char			sym_name[8];	/* Space terminated */
+	char			sym_ptr[AR_PORT_WORD];	/* sgetl() accessed */
+}			Ars_5;
+
+typedef struct {	/* 5.0 ar member format: vax family; 3b family */
+	char			arf_name[16];	/* Space terminated */
+	char			arf_date[AR_PORT_WORD];	/* sgetl() accessed */
+	char			arf_uid[AR_PORT_WORD];	/* sgetl() accessed */
+	char			arf_gid[AR_PORT_WORD];	/* sgetl() accessed */
+	char			arf_mode[AR_PORT_WORD];	/* sgetl() accessed */
+	char			arf_size[AR_PORT_WORD];	/* sgetl() accessed */
+}			Arf_5;
+
+typedef struct {	/* Portable (6.0) ar format: vax family; 3b family */
+	char			ar_name[16];	/* Space terminated */
+	/* left-adjusted fields; decimal ascii; blank filled */
+	char			ar_date[12];	
+	char			ar_uid[6];
+	char			ar_gid[6];
+	char			ar_mode[8];	/* octal ascii */
+	char			ar_size[10];
+	/* special end-of-header string (AR_PORT_END_MAGIC) */
+	char			ar_fmag[2];	
+}			Ar_port;
+
+enum ar_type {
+		AR_5,
+		AR_PORT
+};
+
+typedef unsigned int ar_port_word; // must be 4-bytes long
+
+typedef struct {
+	FILE			*fd;
+	/* to distiguish ar format */
+	enum ar_type		type;
+	/* where first ar member header is at */
+	long			first_ar_mem;
+	/* where the symbol lookup starts */
+	long			sym_begin;
+	/* the number of symbols available */
+	long			num_symbols;
+	/* length of symbol directory file */
+	long			sym_size;
+	Arh_5			arh_5;
+	Ars_5			ars_5;
+	Arf_5			arf_5;
+	Ar_port			ar_port;
+}			Ar;
+
+/*
+ * Static variables
+ */
+
+/*
+ * File table of contents
+ */
+extern	timestruc_t&	read_archive(register Name target);
+static	Boolean		open_archive(char *filename, register Ar *arp);
+static	void		close_archive(register Ar *arp);
+static	Boolean		read_archive_dir(register Ar *arp, Name library, char **long_names_table);
+static	void		translate_entry(register Ar *arp, Name target, register Property member, char **long_names_table);
+static	long		sgetl(char *);
+
+/*
+ *	read_archive(target)
+ *
+ *	Read the contents of an ar file.
+ *
+ *	Return value:
+ *				The time the member was created
+ *
+ *	Parameters:
+ *		target		The member to find time for
+ *
+ *	Global variables used:
+ *		empty_name 	The Name ""
+ */
+
+int read_member_header (Ar_port *header, FILE *fd, char* filename);
+int process_long_names_member (register Ar *arp, char **long_names_table, char *filename);
+
+timestruc_t&
+read_archive(register Name target)
+{
+	register Property       member;
+	wchar_t			*slash;
+	String_rec		true_member_name;
+	wchar_t			buffer[STRING_BUFFER_LENGTH];
+	register Name		true_member = NULL;
+	Ar                      ar;
+	char			*long_names_table = NULL; /* Table of long
+							     member names */
+
+	member = get_prop(target->prop, member_prop);
+	/*
+	 * Check if the member has directory component.
+	 * If so, remove the dir and see if we know the date.
+	 */
+	if (member->body.member.member != NULL) {
+		Wstring member_string(member->body.member.member);
+		wchar_t * wcb = member_string.get_string();
+		if((slash = (wchar_t *) wsrchr(wcb, (int) slash_char)) != NULL) {
+			INIT_STRING_FROM_STACK(true_member_name, buffer);
+			append_string(member->body.member.library->string_mb,
+				      &true_member_name,
+				      FIND_LENGTH);
+			append_char((int) parenleft_char, &true_member_name);
+			append_string(slash + 1, &true_member_name, FIND_LENGTH);
+			append_char((int) parenright_char, &true_member_name);
+			true_member = GETNAME(true_member_name.buffer.start,
+					      FIND_LENGTH);
+			if (true_member->stat.time != file_no_time) {
+				target->stat.time = true_member->stat.time;
+				return target->stat.time;
+			}
+		}
+	}
+	if (open_archive(member->body.member.library->string_mb, &ar) == failed) {
+		if (errno == ENOENT) {
+			target->stat.stat_errno = ENOENT;
+			close_archive(&ar);
+			if (member->body.member.member == NULL) {
+				member->body.member.member = empty_name;
+			}
+			return target->stat.time = file_doesnt_exist;
+		} else {
+			fatal(catgets(catd, 1, 1, "Can't access archive `%s': %s"),
+			      member->body.member.library->string_mb,
+			      errmsg(errno));
+		}
+	}
+	if (target->stat.time == file_no_time) {
+		if (read_archive_dir(&ar, member->body.member.library, 
+				     &long_names_table)
+		    == failed){
+			fatal(catgets(catd, 1, 2, "Can't access archive `%s': %s"),
+			      member->body.member.library->string_mb,
+			      errmsg(errno));
+		}
+	}
+	if (member->body.member.entry != NULL) {
+		translate_entry(&ar, target, member,&long_names_table);
+	}
+	close_archive(&ar);
+	if (long_names_table) {
+		retmem_mb(long_names_table);
+	}
+	if (true_member != NULL) {
+		target->stat.time = true_member->stat.time;
+	}
+	if (target->stat.time == file_no_time) {
+		target->stat.time = file_doesnt_exist;
+	}
+	return target->stat.time;
+}
+
+/*
+ *	open_archive(filename, arp)
+ *
+ *	Return value:
+ *				Indicates if open failed or not
+ *
+ *	Parameters:
+ *		filename	The name of the archive we need to read
+ *		arp		Pointer to ar file description block
+ *
+ *	Global variables used:
+ */
+static Boolean
+open_archive(char *filename, register Ar *arp)
+{
+	int			fd;
+	char			mag_5[AR_5_MAGIC_LENGTH];
+	char			mag_port[AR_PORT_MAGIC_LENGTH];
+	char			buffer[4];
+
+	arp->fd = NULL;
+	fd = open_vroot(filename, O_RDONLY, 0, NULL, VROOT_DEFAULT);
+	if ((fd < 0) || ((arp->fd = fdopen(fd, "r")) == NULL)) {
+		return failed;
+	}
+	(void) fcntl(fileno(arp->fd), F_SETFD, 1);
+
+#if !defined(SUN5_0) && !defined(linux) //XXX
+	/* Read enough of the archive to distinguish between the formats */
+	if (fread(mag_5, AR_5_MAGIC_LENGTH, 1, arp->fd) != 1) {
+		return failed;
+	}
+	if (IS_EQUALN(mag_5, AR_5_MAGIC, AR_5_MAGIC_LENGTH)) {
+		arp->type = AR_5;
+		/* Must read in header to set necessary info */
+		if (fseek(arp->fd, 0L, 0) != 0 ||
+		    fread((char *) &arp->arh_5, sizeof (Arh_5), 1, arp->fd) !=
+									1) {
+			return failed;
+		}
+		arp->sym_begin = ftell(arp->fd);
+		arp->num_symbols = sgetl(arp->arh_5.ar_syms);
+		arp->first_ar_mem = arp->sym_begin +
+					sizeof (Ars_5) * arp->num_symbols;
+		arp->sym_size = 0L;
+		return succeeded;
+	}
+	if (fseek(arp->fd, 0L, 0) != 0) {
+		return failed;
+	}
+#endif
+	if (fread(mag_port, AR_PORT_MAGIC_LENGTH, 1, arp->fd) != 1) {
+		return failed;
+	}
+	if (IS_EQUALN(mag_port, AR_PORT_MAGIC, AR_PORT_MAGIC_LENGTH)) {
+		arp->type = AR_PORT;
+		/*
+		 * Read in first member header to find out if there is 
+		 * a symbol definition table.
+		 */
+
+		int ret = read_member_header(&arp->ar_port, arp->fd, filename);
+		if (ret == failed) {
+			return failed;
+		} else if(ret == -1) {
+			/* There is no member header - empty archive */
+			arp->sym_size = arp->num_symbols = arp->sym_begin = 0L;
+			arp->first_ar_mem = ftell(arp->fd);
+			return succeeded;
+		}
+		/*
+		 * The following values are the default if there is 
+		 * no symbol directory and long member names.
+		 */
+		arp->sym_size = arp->num_symbols = arp->sym_begin = 0L;
+		arp->first_ar_mem = ftell(arp->fd) - (long) sizeof (Ar_port);
+
+		/*
+		 * Do we have a symbol table? A symbol table is always
+		 * the first member in an archive. In 4.1.x it has the 
+		 * name __.SYMDEF, in SVr4, it has the name "/        "
+		 */
+/*
+#ifdef SUN5_0
+		MBSTOWCS(wcs_buffer, NOCATGETS("/               "));
+		if (IS_WEQUALN(arp->ar_port.ar_name, wcs_buffer, 16)) {
+#else
+		MBSTOWCS(wcs_buffer, NOCATGETS("__.SYMDEF       "));
+		if (IS_WEQUALN(arp->ar_port.ar_name, wcs_buffer, 16)) {
+#endif
+ */
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+		if (IS_EQUALN(arp->ar_port.ar_name,
+			      NOCATGETS("/               "),
+			      16)) {
+#else
+		if (IS_EQUALN(arp->ar_port.ar_name,
+			      NOCATGETS("__.SYMDEF       "),
+			      16)) {
+#endif
+			if (sscanf(arp->ar_port.ar_size,
+				   "%ld",
+				   &arp->sym_size) != 1) {
+				return failed;
+			}
+			arp->sym_size += (arp->sym_size & 1); /* round up */
+			if (fread(buffer, sizeof buffer, 1, arp->fd) != 1) {
+				return failed;
+			}
+			arp->num_symbols = sgetl(buffer);
+			arp->sym_begin = ftell(arp->fd);
+			arp->first_ar_mem = arp->sym_begin +
+						arp->sym_size - sizeof buffer;
+		}
+		return succeeded;
+	}
+	fatal(catgets(catd, 1, 3, "`%s' is not an archive"), filename);
+	/* NOTREACHED */
+	return failed;
+}
+
+
+/*
+ *	close_archive(arp)
+ *
+ *	Parameters:
+ *		arp		Pointer to ar file description block
+ *
+ *	Global variables used:
+ */
+static void
+close_archive(register Ar *arp)
+{
+	if (arp->fd != NULL) {
+		(void) fclose(arp->fd);
+	}
+}
+
+/*
+ *	read_archive_dir(arp, library, long_names_table)
+ *
+ *	Reads the directory of an archive and enters all
+ *	the members into the make symboltable in lib(member) format
+ *	with their dates.
+ *
+ *	Parameters:
+ *		arp		Pointer to ar file description block
+ *		library		Name of lib to enter members for.
+ *				Used to form "lib(member)" string.
+ *		long_names_table table that contains list of members
+ * 				with names > 15 characters long
+ *
+ *	Global variables used:
+ */
+static Boolean
+#if defined(SUN5_0) || defined(linux) //XXX
+read_archive_dir(register Ar *arp, Name library, char **long_names_table)
+#else
+read_archive_dir(register Ar *arp, Name library, char **)
+#endif
+{
+	wchar_t			*name_string;
+	wchar_t			*member_string;
+	register long		len;
+	register wchar_t	*p;
+	register char		*q;
+	register Name		name;
+	Property		member;
+	long			ptr;
+	long			date;
+
+#if defined(SUN5_0) || defined(linux) //XXX
+	int			offset;
+
+	/*
+	 * If any of the members has a name > 15 chars,
+	 * it will be found here.
+	 */
+	if (process_long_names_member(arp, long_names_table, library->string_mb) == failed) {
+		return failed;
+	}
+#endif
+	name_string = ALLOC_WC((int) (library->hash.length +
+				      (int) ar_member_name_len * 2));
+	(void) mbstowcs(name_string, library->string_mb, (int) library->hash.length);
+	member_string = name_string + library->hash.length;
+	*member_string++ = (int) parenleft_char;
+
+	if (fseek(arp->fd, arp->first_ar_mem, 0) != 0) {
+		goto read_error;
+	}
+	/* Read the directory using the appropriate format */
+	switch (arp->type) {
+	case AR_5:
+	    for (;;) {
+		if (fread((char *) &arp->arf_5, sizeof arp->arf_5, 1, arp->fd)
+		    != 1) {
+			if (feof(arp->fd)) {
+				return succeeded;
+			}
+			break;
+		}
+		len = sizeof arp->arf_5.arf_name;
+		for (p = member_string, q = arp->arf_5.arf_name;
+		     (len > 0) && (*q != (int) nul_char) && !isspace(*q);
+		     ) {
+			MBTOWC(p, q);
+			p++;
+			q++;
+		}
+		*p++ = (int) parenright_char;
+		*p = (int) nul_char;
+		name = GETNAME(name_string, FIND_LENGTH);
+		/*
+		 * [tolik] Fix for dmake bug 1234018.
+		 * If name->stat.time is already set, then it should not
+		 * be changed. (D)make propogates time stamp for one
+		 * member, and when it calls exists() for another member,
+		 * the first one may be changed.
+		 */
+		if(name->stat.time == file_no_time) {
+			name->stat.time.tv_sec = sgetl(arp->arf_5.arf_date);
+			name->stat.time.tv_nsec = LONG_MAX;
+		}
+		name->is_member = library->is_member;
+		member = maybe_append_prop(name, member_prop);
+		member->body.member.library = library;
+		*--p = (int) nul_char;
+		if (member->body.member.member == NULL) {
+			member->body.member.member =
+			  GETNAME(member_string, FIND_LENGTH);
+		}
+		ptr = sgetl(arp->arf_5.arf_size);
+		ptr += (ptr & 1);
+		if (fseek(arp->fd, ptr, 1) != 0) {
+			goto read_error;
+		}
+	    }
+	    break;
+	case AR_PORT:
+	    for (;;) {
+		    if ((fread((char *) &arp->ar_port,
+			       sizeof arp->ar_port,
+			       1,
+			       arp->fd) != 1) ||
+			!IS_EQUALN(arp->ar_port.ar_fmag,
+				   AR_PORT_END_MAGIC,
+				   sizeof arp->ar_port.ar_fmag)) {
+			    if (feof(arp->fd)) {
+				    return succeeded;
+			    }
+			    fatal(
+				catgets(catd, 1, 28, "Read error in archive `%s': invalid archive file member header at 0x%x"),
+				library->string_mb,
+				ftell(arp->fd)
+			    );
+		    }
+#if defined(SUN5_0) || defined(linux) //XXX
+		    /* If it's a long name, retrieve it from long name table */
+		    if (arp->ar_port.ar_name[0] == '/') {
+			    /*
+			     * "len" is used for hashing the string.
+			     * We're using "ar_member_name_len" instead of
+			     * the actual name length since it's the longest
+			     * string the "ar" command can handle at this
+			     * point.
+			     */
+			    len = ar_member_name_len;
+			    sscanf(arp->ar_port.ar_name + 1,
+				   "%ld",
+				   &offset);
+			    q = *long_names_table + offset;
+		    } else {
+			    q = arp->ar_port.ar_name;	
+			    len = sizeof arp->ar_port.ar_name;
+		    }
+#else
+		    q = arp->ar_port.ar_name;	
+		    len = sizeof arp->ar_port.ar_name;
+#endif
+		    
+		    for (p = member_string;
+			 (len > 0) &&
+			 (*q != (int) nul_char) &&
+			 !isspace(*q) &&
+			 (*q != (int) slash_char);
+			 ) {
+			    MBTOWC(p, q);
+			    p++;
+			    q++;
+		    }
+		    *p++ = (int) parenright_char;
+		    *p = (int) nul_char;
+		    name = GETNAME(name_string, FIND_LENGTH);
+		    name->is_member = library->is_member;
+		    member = maybe_append_prop(name, member_prop);
+		    member->body.member.library = library;
+		    *--p = (int) nul_char;
+		    if (member->body.member.member == NULL) {
+			    member->body.member.member =
+			      GETNAME(member_string, FIND_LENGTH);
+		    }
+		    if (sscanf(arp->ar_port.ar_date, "%ld", &date) != 1) {
+			    WCSTOMBS(mbs_buffer, name_string);
+			    fatal(catgets(catd, 1, 4, "Bad date field for member `%s' in archive `%s'"),
+				  mbs_buffer,
+				  library->string_mb);
+		    }
+		    /*
+		     * [tolik] Fix for dmake bug 1234018.
+		     */
+		    if(name->stat.time == file_no_time) {
+		   	name->stat.time.tv_sec = date;
+		   	name->stat.time.tv_nsec = LONG_MAX;
+		    }
+		    if (sscanf(arp->ar_port.ar_size, "%ld", &ptr) != 1) {
+			    WCSTOMBS(mbs_buffer, name_string);
+			    fatal(catgets(catd, 1, 5, "Bad size field for member `%s' in archive `%s'"),
+				  mbs_buffer,
+				  library->string_mb);
+		    }
+		    ptr += (ptr & 1);
+		    if (fseek(arp->fd, ptr, 1) != 0) {
+			    goto read_error;
+		    }	
+	    }
+	    break;
+	}
+
+	/* Only here if fread() [or IS_EQUALN()] failed and not at EOF */
+read_error:
+	fatal(catgets(catd, 1, 6, "Read error in archive `%s': %s"),
+	      library->string_mb,
+	      errmsg(errno));
+	    /* NOTREACHED */
+}
+
+
+/*
+ *	process_long_names_member(arp)
+ *
+ *	If the archive contains members with names longer
+ *	than 15 characters, then it has a special member
+ *	with the name "//        " that contains a table
+ *	of null-terminated long names. This member
+ *	is always the first member, after the symbol table
+ *	if it exists.
+ *
+ *	Parameters:
+ *		arp		Pointer to ar file description block
+ *
+ *	Global variables used:
+ */
+int
+process_long_names_member(register Ar *arp, char **long_names_table, char *filename)
+{  
+	Ar_port			*ar_member_header;
+	int			table_size;
+
+	if (fseek(arp->fd, arp->first_ar_mem, 0) != 0) {
+		return failed;
+	}
+	if ((ar_member_header = 
+	     (Ar_port *) alloca((int) sizeof(Ar_port))) == NULL){
+		perror(catgets(catd, 1, 7, "memory allocation failure"));
+		return failed;
+	} 
+	int ret = read_member_header(ar_member_header, arp->fd, filename);
+	if (ret == failed) {
+		return failed;
+	} else if(ret == -1) {
+		/* There is no member header - empty archive */
+		return succeeded;
+	}
+	/* Do we have special member containing long names? */
+	if (IS_EQUALN(ar_member_header->ar_name, 
+		      NOCATGETS("//              "),
+		      16)){
+		if (sscanf(ar_member_header->ar_size,
+			   "%ld",
+			   &table_size) != 1) {
+			return failed;
+		}
+		*long_names_table = (char *) malloc(table_size);
+		/* Read the list of long member names into the table */
+		if (fread(*long_names_table, table_size, 1, arp->fd) != 1) {
+			return failed;
+		}
+		arp->first_ar_mem = ftell(arp->fd);
+	}
+	return succeeded;
+}
+
+/*
+ *	translate_entry(arp, target, member)
+ *
+ *	Finds the member for one lib.a((entry))
+ *
+ *	Parameters:
+ *		arp		Pointer to ar file description block
+ *		target		Target to find member name for
+ *		member		Property to fill in with info
+ *
+ *	Global variables used:
+ */
+static void
+translate_entry(register Ar *arp, Name target, register Property member, char **long_names_table)
+{
+	register int		len;
+	register int		i;
+	wchar_t			*member_string;
+	ar_port_word		*offs;
+	int			strtablen;
+	char			*syms;		 /* string table */
+	char			*csym;		 /* string table */
+	ar_port_word		*offend;	 /* end of offsets table */
+	int			date;
+	register wchar_t	*ap;
+	register char		*hp;
+	int			maxs;
+	int			offset;
+	char		buffer[4];
+
+	if (arp->sym_begin == 0L || arp->num_symbols == 0L) {
+		fatal(catgets(catd, 1, 8, "Cannot find symbol `%s' in archive `%s'"),
+		      member->body.member.entry->string_mb,
+		      member->body.member.library->string_mb);
+	}
+
+	if (fseek(arp->fd, arp->sym_begin, 0) != 0) {
+		goto read_error;
+	}
+	member_string = ALLOC_WC((int) ((int) ar_member_name_len * 2));
+
+	switch (arp->type) {
+	case AR_5:
+		if ((len = member->body.member.entry->hash.length) > 8) {
+			len = 8;
+		}
+		for (i = 0; i < arp->num_symbols; i++) {
+			if (fread((char *) &arp->ars_5,
+				  sizeof arp->ars_5,
+				  1,
+				  arp->fd) != 1) {
+				goto read_error;
+			}
+			if (IS_EQUALN(arp->ars_5.sym_name,
+				      member->body.member.entry->string_mb,
+				      len)) {
+				if ((fseek(arp->fd,
+					   sgetl(arp->ars_5.sym_ptr),
+					   0) != 0) ||
+				    (fread((char *) &arp->arf_5,
+					   sizeof arp->arf_5,
+					   1,
+					   arp->fd) != 1)) {
+					goto read_error;
+				}
+				MBSTOWCS(wcs_buffer, arp->arf_5.arf_name);
+				(void) wsncpy(member_string,
+					      wcs_buffer,
+					      wslen(wcs_buffer));
+				member_string[sizeof(arp->arf_5.arf_name)] =
+								(int) nul_char;
+				member->body.member.member =
+					GETNAME(member_string, FIND_LENGTH);
+				target->stat.time.tv_sec = sgetl(arp->arf_5.arf_date);
+				target->stat.time.tv_nsec = LONG_MAX;
+				return;
+			}
+		}
+		break;
+	case AR_PORT:
+		offs = (ar_port_word *) alloca((int) (arp->num_symbols * AR_PORT_WORD));
+		if (fread((char *) offs,
+			  AR_PORT_WORD,
+			  (int) arp->num_symbols,
+			  arp->fd) != arp->num_symbols) {
+			goto read_error;
+		}
+
+		for(i=0;i<arp->num_symbols;i++) {
+			*((int*)buffer)=offs[i];
+			offs[i]=(ar_port_word)sgetl(buffer);
+		}
+
+		strtablen=arp->sym_size-4-(int) (arp->num_symbols * AR_PORT_WORD);
+		syms = (char *) alloca(strtablen);
+		if (fread(syms,
+			  sizeof (char),
+			  strtablen,
+			  arp->fd) != strtablen) {
+			goto read_error;
+		}
+		offend = &offs[arp->num_symbols];
+		while (offs < offend) {
+			maxs = strlen(member->body.member.entry->string_mb);
+			if(strlen(syms) > maxs)
+				maxs = strlen(syms);
+			if (IS_EQUALN(syms,
+				      member->body.member.entry->string_mb,
+				      maxs)) {
+				if (fseek(arp->fd,
+					  (long) *offs,
+					  0) != 0) {
+					goto read_error;
+				}
+				if ((fread((char *) &arp->ar_port,
+					   sizeof arp->ar_port,
+					   1,
+					   arp->fd) != 1) ||
+				    !IS_EQUALN(arp->ar_port.ar_fmag,
+					       AR_PORT_END_MAGIC,
+					       sizeof arp->ar_port.ar_fmag)) {
+					goto read_error;
+				}
+				if (sscanf(arp->ar_port.ar_date,
+					   "%ld",
+					   &date) != 1) {
+					fatal(catgets(catd, 1, 9, "Bad date field for member `%s' in archive `%s'"),
+					      arp->ar_port.ar_name,
+					      target->string_mb);
+				}
+#if defined(SUN5_0) || defined(linux) //XXX
+		    /* If it's a long name, retrieve it from long name table */
+		    if (arp->ar_port.ar_name[0] == '/') {
+			    sscanf(arp->ar_port.ar_name + 1,
+				   "%ld",
+				   &offset);
+			    len = ar_member_name_len;
+			    hp = *long_names_table + offset;
+		    } else {
+			    len = sizeof arp->ar_port.ar_name;
+			    hp = arp->ar_port.ar_name;	
+		    }
+#else
+		    hp = arp->ar_port.ar_name;	
+#endif
+				ap = member_string;
+				while (*hp &&
+				       (*hp != (int) slash_char) &&
+				       (ap < &member_string[len])) {
+					MBTOWC(ap, hp);
+					ap++;
+					hp++;
+				}
+				*ap = (int) nul_char;
+				member->body.member.member =
+					GETNAME(member_string, FIND_LENGTH);
+				target->stat.time.tv_sec = date;
+				target->stat.time.tv_nsec = LONG_MAX;
+				return;
+			}
+			offs++;
+			while(*syms!='\0') syms++;
+			syms++;
+		}
+	}
+	fatal(catgets(catd, 1, 10, "Cannot find symbol `%s' in archive `%s'"),
+	      member->body.member.entry->string_mb,
+	      member->body.member.library->string_mb);
+	/*NOTREACHED*/
+
+read_error:
+	if (ferror(arp->fd)) {
+		fatal(catgets(catd, 1, 11, "Read error in archive `%s': %s"),
+		      member->body.member.library->string_mb,
+		      errmsg(errno));
+	} else {
+		fatal(catgets(catd, 1, 12, "Read error in archive `%s': Premature EOF"),
+		      member->body.member.library->string_mb);
+	}
+}
+
+/*
+ *	sgetl(buffer)
+ *
+ *	The intent here is to provide a means to make the value of
+ *	bytes in an io-buffer correspond to the value of a long
+ *	in the memory while doing the io a long at a time.
+ *	Files written and read in this way are machine-independent.
+ *
+ *	Return value:
+ *				Long int read from buffer
+ *	Parameters:
+ *		buffer		buffer we need to read long int from
+ *
+ *	Global variables used:
+ */
+static long
+sgetl(register char *buffer)
+{
+	register long		w = 0;
+	register int		i = BITSPERBYTE * AR_PORT_WORD;
+
+	while ((i -= BITSPERBYTE) >= 0) {
+		w |= (long) ((unsigned char) *buffer++) << i;
+	}
+	return w;
+}
+
+
+/*
+ *	read_member_header(header, fd, filename)
+ *
+ *	reads the member header for the 4.1.x and SVr4 archives.
+ *
+ *	Return value:
+ *				fails if read error or member
+ * 				header is not the right format
+ *	Parameters:
+ *		header		There's one before each archive member
+ *		fd		file descriptor for the archive file.
+ *
+ *	Global variables used:
+ */
+int 
+read_member_header(Ar_port *header, FILE *fd, char* filename)
+{
+	int num = fread((char *) header, sizeof (Ar_port), 1, fd);
+	if (num != 1 && feof(fd)) {
+		/* There is no member header - empty archive */
+		return -1;
+	}
+	if ((num != 1) ||
+	    !IS_EQUALN(
+		AR_PORT_END_MAGIC,
+		header->ar_fmag,
+		sizeof (header->ar_fmag)
+	    )
+	) {
+		fatal(
+			catgets(catd, 1, 28, "Read error in archive `%s': invalid archive file member header at 0x%x"),
+			filename,
+			ftell(fd)
+		);
+	}
+	return succeeded;
+}
+
--- /dev/null	2015-05-20 11:04:06.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/common/default.mk.file	2015-05-20 11:04:06.873962511 -0400
@@ -0,0 +1,231 @@
+#
+# 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 1993 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)default.mk.file 1.4 06/12/12
+#
+
+SUFFIXES = .o .c .c~ .cc .cc~ .s .s~ .S .S~ .ln .f .f~ .F .F~ .l .l~ \
+	.mod .mod~ .sym .def .def~ .p .p~ .r .r~ .y .y~ .h .h~ .sh .sh~ \
+	.cps .cps~
+.SUFFIXES: $(SUFFIXES)
+
+# OUTPUT_OPTION should be defined to "-o $@" when
+# the default rules are used for non-local files.
+OUTPUT_OPTION=
+
+#	C language section.
+CC=cc
+CFLAGS=
+CPPFLAGS=
+LINT=lint
+LINTFLAGS=
+COMPILE.c=$(CC) $(CFLAGS) $(CPPFLAGS) -target $(TARGET_ARCH:-%=%) -c
+LINK.c=$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -target $(TARGET_ARCH:-%=%)
+LINT.c=$(LINT) $(LINTFLAGS) $(CPPFLAGS) $(TARGET_ARCH)
+.c:
+	$(LINK.c) -o $@ $< $(LDLIBS)
+.c.ln:
+	$(LINT.c) $(OUTPUT_OPTION) -i $<
+.c.o:
+	$(COMPILE.c) $(OUTPUT_OPTION) $<
+.c.a:
+	$(COMPILE.c) -o $% $<
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+
+#	C language section. yacc.
+YACC=yacc
+YFLAGS=
+YACC.y=$(YACC) $(YFLAGS)
+.y:
+	$(YACC.y) $<
+	$(LINK.c) -o $@ y.tab.c $(LDLIBS)
+	$(RM) y.tab.c
+.y.c:
+	$(YACC.y) $<
+	mv y.tab.c $@
+.y.ln:
+	$(YACC.y) $<
+	$(LINT.c) -o $@ -i y.tab.c
+	$(RM) y.tab.c
+.y.o:
+	$(YACC.y) $<
+	$(COMPILE.c) -o $@ y.tab.c
+	$(RM) y.tab.c
+
+#	C language section. lex.
+LEX=lex
+LFLAGS=
+LEX.l=$(LEX) $(LFLAGS) -t
+.l:
+	$(RM) $*.c
+	$(LEX.l) $< > $*.c
+	$(LINK.c) -o $@ $*.c -ll $(LDLIBS)
+	$(RM) $*.c
+.l.c :
+	$(RM) $@
+	$(LEX.l) $< > $@
+.l.ln:
+	$(RM) $*.c
+	$(LEX.l) $< > $*.c
+	$(LINT.c) -o $@ -i $*.c
+	$(RM) $*.c
+.l.o:
+	$(RM) $*.c
+	$(LEX.l) $< > $*.c
+	$(COMPILE.c) -o $@ $*.c
+	$(RM) $*.c
+
+#       C++ language section.
+CCC=CC
+CCFLAGS=
+COMPILE.cc=$(CCC) $(CCFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
+LINK.cc=$(CCC) $(CCFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
+.cc:
+	$(LINK.cc) -o $@ $< $(LDLIBS)
+.cc.o:
+	$(COMPILE.cc) $(OUTPUT_OPTION) $<
+.cc.a:
+	$(COMPILE.cc) -o $% $<
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+
+#	FORTRAN section.
+FC=f77
+FFLAGS=
+COMPILE.f=$(FC) $(FFLAGS) $(TARGET_ARCH) -c
+LINK.f=$(FC) $(FFLAGS) $(LDFLAGS) $(TARGET_ARCH)
+COMPILE.F=$(FC) $(FFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
+LINK.F=$(FC) $(FFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
+.f:
+	$(LINK.f) -o $@ $< $(LDLIBS)
+.f.o:
+	$(COMPILE.f) $(OUTPUT_OPTION) $<
+.f.a:
+	$(COMPILE.f) -o $% $<
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+.F:
+	$(LINK.F) -o $@ $< $(LDLIBS)
+.F.o:
+	$(COMPILE.F) $(OUTPUT_OPTION) $<
+.F.a:
+	$(COMPILE.F) -o $% $<
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+
+#	FORTRAN section. ratfor.
+RFLAGS=
+COMPILE.r=$(FC) $(FFLAGS) $(RFLAGS) $(TARGET_ARCH) -c
+LINK.r=$(FC) $(FFLAGS) $(RFLAGS) $(LDFLAGS) $(TARGET_ARCH)
+.r:
+	$(LINK.r) -o $@ $< $(LDLIBS)
+.r.o:
+	$(COMPILE.r) $(OUTPUT_OPTION) $<
+.r.a:
+	$(COMPILE.r) -o $% $<
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+
+#	Modula-2 section.
+M2C=m2c
+M2FLAGS=
+MODFLAGS=
+DEFFLAGS=
+COMPILE.def=$(M2C) $(M2FLAGS) $(DEFFLAGS) $(TARGET_ARCH)
+COMPILE.mod=$(M2C) $(M2FLAGS) $(MODFLAGS) $(TARGET_ARCH)
+.def.sym:
+	$(COMPILE.def) -o $@ $<
+.mod:
+	$(COMPILE.mod) -o $@ -e $@ $<
+.mod.o:
+	$(COMPILE.mod) -o $@ $<
+.mod.a:
+	$(COMPILE.mod) -o $% $<
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+
+#	Pascal section.
+PC=pc
+PFLAGS=
+COMPILE.p=$(PC) $(PFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
+LINK.p=$(PC) $(PFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
+.p:
+	$(LINK.p) -o $@ $< $(LDLIBS)
+.p.o:
+	$(COMPILE.p) $(OUTPUT_OPTION) $<
+.p.a:
+	$(COMPILE.p) -o $% $<
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+
+#	Assembly section.
+AS=as
+ASFLAGS=
+COMPILE.s=$(AS) $(ASFLAGS) $(TARGET_MACH)
+COMPILE.S=$(CC) $(ASFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
+.s.o:
+	$(COMPILE.s) -o $@ $<
+.s.a:
+	$(COMPILE.s) -o $% $<
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+.S.o:
+	$(COMPILE.S) -o $@ $<
+.S.a:
+	$(COMPILE.S) -o $% $<
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+
+#	Shell section.
+.sh:
+	$(RM) $@
+	cat $< > $@
+	chmod +x $@
+
+#	NeWS section
+CPS=cps
+CPSFLAGS=
+.cps.h:
+	$(CPS) $(CPSFLAGS) $*.cps
+
+#	Miscellaneous section.
+LD=ld
+LDFLAGS=
+LDLIBS=
+MAKE=make
+RM=rm -f
+AR=ar
+ARFLAGS=rv
+GET=/usr/sccs/get
+GFLAGS=
+
+markfile.o:	markfile
+	echo "static char _sccsid[] = \"`grep @'(#)' markfile`\";" > markfile.c
+	cc -c markfile.c
+	$(RM) markfile.c
+
+SCCSFLAGS=
+SCCSGETFLAGS=-s
+.SCCS_GET:
+	sccs $(SCCSFLAGS) get $(SCCSGETFLAGS) $@ -G$@
--- /dev/null	2015-05-20 11:04:07.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/common/depvar.cc	2015-05-20 11:04:07.095279693 -0400
@@ -0,0 +1,149 @@
+/*
+ * 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 1995 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)depvar.cc 1.14 06/12/12
+ */
+
+#pragma	ident	"@(#)depvar.cc	1.14	06/12/12"
+
+/*
+ * Included files
+ */
+#include <mk/defs.h>
+#include <mksh/misc.h>		/* getmem() */
+
+/*
+ * This file deals with "Dependency Variables".
+ * The "-V var" command line option is used to indicate
+ * that var is a dependency variable.  Used in conjunction with
+ * the -P option the user is asking if the named variables affect
+ * the dependencies of the given target.
+ */
+
+struct _Depvar {
+	Name		name;		/* Name of variable */
+	struct _Depvar	*next;		/* Linked list */
+	Boolean		cmdline;	/* Macro defined on the cmdline? */
+};
+
+typedef	struct _Depvar	*Depvar;
+
+static	Depvar		depvar_list;
+static	Depvar		*bpatch = &depvar_list;
+static	Boolean		variant_deps;
+
+/*
+ * Add a name to the list.
+ */
+
+void
+depvar_add_to_list(Name name, Boolean cmdline)
+{
+	Depvar		dv;
+
+#ifdef SUNOS4_AND_AFTER
+	dv = ALLOC(Depvar);
+#else
+	dv = (Depvar) Malloc(sizeof(struct _Depvar));
+#endif
+	dv->name = name;
+	dv->next = NULL;
+	dv->cmdline = cmdline;
+	*bpatch = dv;
+	bpatch = &dv->next;
+}
+
+/*
+ * The macro `name' has been used in either the left-hand or
+ * right-hand side of a dependency.  See if it is in the
+ * list.  Two things are looked for.  Names given as args
+ * to the -V list are checked so as to set the same/differ
+ * output for the -P option.  Names given as macro=value
+ * command-line args are checked and, if found, an NSE
+ * warning is produced.
+ */
+void
+depvar_dep_macro_used(Name name)
+{
+	Depvar		dv;
+
+	for (dv = depvar_list; dv != NULL; dv = dv->next) {
+		if (name == dv->name) {
+#ifdef NSE
+#ifdef SUNOS4_AND_AFTER
+			if (dv->cmdline) {
+#else
+			if (is_true(dv->cmdline)) {
+#endif
+				nse_dep_cmdmacro(dv->name->string);
+			}
+#endif
+			variant_deps = true;
+			break;
+		}
+	}
+}
+
+#ifdef NSE
+/*
+ * The macro `name' has been used in either the argument
+ * to a cd before a recursive make.  See if it was
+ * defined on the command-line and, if so, complain.
+ */
+void
+depvar_rule_macro_used(Name name)
+{
+	Depvar		dv;
+
+	for (dv = depvar_list; dv != NULL; dv = dv->next) {
+		if (name == dv->name) {
+#ifdef SUNOS4_AND_AFTER
+			if (dv->cmdline) {
+#else
+			if (is_true(dv->cmdline)) {
+#endif
+				nse_rule_cmdmacro(dv->name->string);
+			}
+			break;
+		}
+	}
+}
+#endif
+
+/*
+ * Print the results.  If any of the Dependency Variables
+ * affected the dependencies then the dependencies potentially
+ * differ because of these variables.
+ */
+void
+depvar_print_results(void)
+{
+	if (variant_deps) {
+		printf(catgets(catd, 1, 234, "differ\n"));
+	} else {
+		printf(catgets(catd, 1, 235, "same\n"));
+	}
+}
+
--- /dev/null	2015-05-20 11:04:07.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/common/dist.cc	2015-05-20 11:04:07.373082873 -0400
@@ -0,0 +1,581 @@
+/*
+ * 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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)dist.cc 1.35 06/12/12
+ */
+
+#pragma	ident	"@(#)dist.cc	1.25	96/03/12"
+
+#ifdef DISTRIBUTED
+/*
+ *      dist.cc
+ *
+ *      Deal with the distributed processing
+ */
+
+#include <avo/err.h>
+#include <avo/find_dir.h>
+#include <avo/util.h>
+#include <dm/Avo_AcknowledgeMsg.h>
+#include <dm/Avo_DoJobMsg.h>
+#include <dm/Avo_JobResultMsg.h>
+#include <mk/defs.h>
+#include <mksh/misc.h>		/* getmem() */
+#include <rw/pstream.h>
+#include <rw/queuecol.h>
+#include <rw/xdrstrea.h>
+#include <signal.h>
+#ifdef linux
+#include <sstream>
+using namespace std;
+#else
+#include <strstream.h>
+#endif
+#include <sys/stat.h>		/* stat() */
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <errno.h>
+
+/*
+ * Defined macros
+ */
+
+#define AVO_BLOCK_INTERUPTS sigfillset(&newset) ; \
+        sigprocmask(SIG_SETMASK, &newset, &oldset)
+ 
+#define AVO_UNBLOCK_INTERUPTS \
+        sigprocmask(SIG_SETMASK, &oldset, &newset)
+
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+int		dmake_ifd; 
+FILE*		dmake_ifp; 
+XDR 		xdrs_in;
+
+int		dmake_ofd;
+FILE*		dmake_ofp;
+XDR 		xdrs_out;
+
+// These instances are required for the RWfactory.
+static Avo_JobResultMsg dummyJobResultMsg;
+static Avo_AcknowledgeMsg dummyAcknowledgeMsg;
+static int firstAcknowledgeReceived = 0;
+ 
+int		rxmPid = 0;
+
+/*
+ * File table of contents
+ */
+static void	set_dmake_env_vars(void);
+
+/*
+ * void
+ * startup_rxm(void)
+ *
+ * When startup_rxm() is called, read_command_options() and
+ * read_files_and_state() have already been read, so DMake
+ * will now know what options to pass to rxm.
+ *
+ * rxm
+ *     [ -k ] [ -n ]
+ *     [ -c <dmake_rcfile> ]
+ *     [ -g <dmake_group> ]
+ *     [ -j <dmake_max_jobs> ]
+ *     [ -m <dmake_mode> ]
+ *     [ -o <dmake_odir> ]
+ *     <read_fd> <write_fd>
+ *
+ * rxm will, among other things, read the rc file.
+ *
+ */
+void
+startup_rxm(void)
+{
+	Name		dmake_name;
+	Name		dmake_value;
+	Avo_err		*find_run_dir_err;
+	int		pipe1[2], pipe2[2];
+	Property	prop;
+	char		*run_dir;
+	char		rxm_command[MAXPATHLEN];
+	int		rxm_debug = 0;
+
+	int 		length;
+	char *		env;
+
+	firstAcknowledgeReceived = 0;
+	/*
+	 * Create two pipes, one for dmake->rxm, and one for rxm->dmake.
+	 * pipe1 is dmake->rxm,
+	 * pipe2 is rxm->dmake.
+	 */
+	if ((pipe(pipe1) < 0) || (pipe(pipe2) < 0)) {
+		fatal(catgets(catd, 1, 245, "pipe() failed: %s"), errmsg(errno));
+	}
+
+	set_dmake_env_vars();
+
+	if ((rxmPid = fork()) < 0) {	/* error */
+		fatal(catgets(catd, 1, 246, "fork() failed: %s"), errmsg(errno));
+	} else if (rxmPid > 0) {	/* parent, dmake */
+		dmake_ofd = pipe1[1];	// write side of pipe
+		if (!(dmake_ofp = fdopen(dmake_ofd, "a"))) {
+			fatal(catgets(catd, 1, 247, "fdopen() failed: %s"), errmsg(errno));
+		}
+		xdrstdio_create(&xdrs_out, dmake_ofp, XDR_ENCODE);
+
+		dmake_ifd = pipe2[0];	// read side of pipe
+		if (!(dmake_ifp = fdopen(dmake_ifd, "r"))) {
+			fatal(catgets(catd, 1, 248, "fdopen() failed: %s"), errmsg(errno));
+		}
+		xdrstdio_create(&xdrs_in, dmake_ifp, XDR_DECODE);
+
+		close(pipe1[0]);	// read side
+		close(pipe2[1]);	// write side
+	} else {			/* child, rxm */
+		close(pipe1[1]);	// write side
+		close(pipe2[0]);	// read side
+
+		/* Find the run directory of dmake, for rxm. */
+		find_run_dir_err = avo_find_run_dir(&run_dir);
+		if (find_run_dir_err) {
+			delete find_run_dir_err;
+			/* Use the path to find rxm. */
+			(void) sprintf(rxm_command, NOCATGETS("rxm"));
+		} else {
+			/* Use the run dir of dmake for rxm. */
+			(void) sprintf(rxm_command, NOCATGETS("%s/rxm"), run_dir);
+		}
+
+		if (continue_after_error) {
+			(void) strcat(rxm_command, NOCATGETS(" -k"));
+		}
+		if (do_not_exec_rule) {
+			(void) strcat(rxm_command, NOCATGETS(" -n"));
+		}
+		if (rxm_debug) {
+			(void) strcat(rxm_command, NOCATGETS(" -S"));
+		}
+		if (send_mtool_msgs) {
+			(void) sprintf(&rxm_command[strlen(rxm_command)],
+			               NOCATGETS(" -O %d"),
+			               mtool_msgs_fd);
+		}
+		MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_RCFILE"));
+		dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
+		if (((prop = get_prop(dmake_name->prop, macro_prop)) != NULL) &&
+		    ((dmake_value = prop->body.macro.value) != NULL)) {
+			(void) sprintf(&rxm_command[strlen(rxm_command)],
+			               NOCATGETS(" -c %s"),
+			               dmake_value->string_mb);
+		} else {
+			length = 2 + strlen(NOCATGETS("DMAKE_RCFILE"));
+			env = getmem(length);
+			(void) sprintf(env,
+			               "%s=",
+			               NOCATGETS("DMAKE_RCFILE"));
+			(void) putenv(env);
+		}
+		MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_GROUP"));
+		dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
+		if (((prop = get_prop(dmake_name->prop, macro_prop)) != NULL) &&
+		    ((dmake_value = prop->body.macro.value) != NULL)) {
+			(void) sprintf(&rxm_command[strlen(rxm_command)],
+			               NOCATGETS(" -g %s"),
+			               dmake_value->string_mb);
+		} else {
+			length = 2 + strlen(NOCATGETS("DMAKE_GROUP"));
+			env = getmem(length);
+			(void) sprintf(env,
+			               "%s=",
+			               NOCATGETS("DMAKE_GROUP"));
+			(void) putenv(env);
+		}
+		MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MAX_JOBS"));
+		dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
+		if (((prop = get_prop(dmake_name->prop, macro_prop)) != NULL) &&
+		    ((dmake_value = prop->body.macro.value) != NULL)) {
+			(void) sprintf(&rxm_command[strlen(rxm_command)],
+			               NOCATGETS(" -j %s"),
+			               dmake_value->string_mb);
+		} else {
+			length = 2 + strlen(NOCATGETS("DMAKE_MAX_JOBS"));
+			env = getmem(length);
+			(void) sprintf(env,
+			               "%s=",
+			               NOCATGETS("DMAKE_MAX_JOBS"));
+			(void) putenv(env);
+		}
+		MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MODE"));
+		dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
+		if (((prop = get_prop(dmake_name->prop, macro_prop)) != NULL) &&
+		    ((dmake_value = prop->body.macro.value) != NULL)) {
+			(void) sprintf(&rxm_command[strlen(rxm_command)],
+			               NOCATGETS(" -m %s"),
+			               dmake_value->string_mb);
+		} else {
+			length = 2 + strlen(NOCATGETS("DMAKE_MODE"));
+			env = getmem(length);
+			(void) sprintf(env,
+			               "%s=",
+			               NOCATGETS("DMAKE_MODE"));
+			(void) putenv(env);
+		}
+		MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_ODIR"));
+		dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
+		if (((prop = get_prop(dmake_name->prop, macro_prop)) != NULL) &&
+		    ((dmake_value = prop->body.macro.value) != NULL)) {
+			(void) sprintf(&rxm_command[strlen(rxm_command)],
+			               NOCATGETS(" -o %s"),
+			               dmake_value->string_mb);
+		} else {
+			length = 2 + strlen(NOCATGETS("DMAKE_ODIR"));
+			env = getmem(length);
+			(void) sprintf(env,
+			               "%s=",
+			               NOCATGETS("DMAKE_ODIR"));
+			(void) putenv(env);
+		}
+
+		(void) sprintf(&rxm_command[strlen(rxm_command)],
+		               NOCATGETS(" %d %d"),
+		               pipe1[0], pipe2[1]);
+#ifdef linux
+		execl(NOCATGETS("/bin/sh"),
+#else
+		execl(NOCATGETS("/usr/bin/sh"),
+#endif
+		      NOCATGETS("sh"),
+		      NOCATGETS("-c"),
+		      rxm_command,
+		      (char *)NULL);
+		_exit(127);
+	}
+}
+
+/*
+ * static void
+ * set_dmake_env_vars()
+ *
+ * Sets the DMAKE_* environment variables for rxm and rxs.
+ *	DMAKE_PWD
+ *	DMAKE_NPWD
+ *	DMAKE_UMASK
+ *	DMAKE_SHELL
+ */
+static void
+set_dmake_env_vars()
+{
+	char		*current_netpath;
+	char		*current_path;
+	static char	*env;
+	int		length;
+	char		netpath[MAXPATHLEN];
+	mode_t		um;
+	char		um_buf[MAXPATHLEN];
+	Name		dmake_name;
+	Name		dmake_value;
+	Property	prop;
+
+#ifdef REDIRECT_ERR
+	/* Set __DMAKE_REDIRECT_STDERR */
+	length = 2 + strlen(NOCATGETS("__DMAKE_REDIRECT_STDERR")) + 1;
+	env = getmem(length);
+	(void) sprintf(env,
+	               "%s=%s",
+	               NOCATGETS("__DMAKE_REDIRECT_STDERR"),
+	               out_err_same ? NOCATGETS("0") : NOCATGETS("1"));
+	(void) putenv(env);
+#endif
+
+	/* Set DMAKE_PWD to the current working directory */
+	current_path = get_current_path();
+	length = 2 + strlen(NOCATGETS("DMAKE_PWD")) + strlen(current_path);
+	env = getmem(length);
+	(void) sprintf(env,
+	               "%s=%s",
+	               NOCATGETS("DMAKE_PWD"),
+	               current_path);
+	(void) putenv(env);
+
+	/* Set DMAKE_NPWD to machine:pathname */
+	if (avo_path_to_netpath(current_path, netpath)) {
+		current_netpath = netpath;
+	} else {
+		current_netpath = current_path;
+	}
+	length = 2 + strlen(NOCATGETS("DMAKE_NPWD")) + strlen(current_netpath);
+	env = getmem(length);
+	(void) sprintf(env,
+	               "%s=%s",
+	               NOCATGETS("DMAKE_NPWD"),
+	               current_netpath);
+	(void) putenv(env);
+
+	/* Set DMAKE_UMASK to the value of umask */
+	um = umask(0);
+	umask(um);
+	(void) sprintf(um_buf, NOCATGETS("%ul"), um);
+	length = 2 + strlen(NOCATGETS("DMAKE_UMASK")) + strlen(um_buf);
+	env = getmem(length);
+	(void) sprintf(env,
+	               "%s=%s",
+	               NOCATGETS("DMAKE_UMASK"),
+	               um_buf);
+	(void) putenv(env);
+
+	if (((prop = get_prop(shell_name->prop, macro_prop)) != NULL) &&
+	    ((dmake_value = prop->body.macro.value) != NULL)) {
+		length = 2 + strlen(NOCATGETS("DMAKE_SHELL")) +
+		         strlen(dmake_value->string_mb);
+		env = getmem(length);
+		(void) sprintf(env,
+	    	           "%s=%s",
+	    	           NOCATGETS("DMAKE_SHELL"),
+	     	           dmake_value->string_mb);
+		(void) putenv(env);
+	}
+	MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_OUTPUT_MODE"));
+	dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
+	if (((prop = get_prop(dmake_name->prop, macro_prop)) != NULL) &&
+	    ((dmake_value = prop->body.macro.value) != NULL)) {
+		length = 2 + strlen(NOCATGETS("DMAKE_OUTPUT_MODE")) +
+		         strlen(dmake_value->string_mb);
+		env = getmem(length);
+		(void) sprintf(env,
+	    	           "%s=%s",
+	    	           NOCATGETS("DMAKE_OUTPUT_MODE"),
+	     	           dmake_value->string_mb);
+		(void) putenv(env);
+	}
+}
+
+/*
+ * void
+ * distribute_rxm(Avo_DoJobMsg *dmake_job_msg)
+ *
+ * Write the DMake rule to be distributed down the pipe to rxm.
+ *
+ */
+void
+distribute_rxm(Avo_DoJobMsg *dmake_job_msg)
+{
+	/* Add all dynamic env vars to the dmake_job_msg. */
+	setvar_envvar(dmake_job_msg);
+
+	/*
+	 * Copying dosys()...
+	 * Stat .make.state to see if we'll need to reread it later
+	 */
+	make_state->stat.time = file_no_time;
+	(void)exists(make_state);
+	make_state_before = make_state->stat.time;
+
+	// Wait for the first Acknowledge message from the rxm process
+	// before sending the first message.
+	if (!firstAcknowledgeReceived) {
+		firstAcknowledgeReceived++;
+		Avo_AcknowledgeMsg *msg = getAcknowledgeMsg();
+		if (msg) {
+			delete msg;
+		}
+	}
+
+	RWCollectable *doJobMsg = (RWCollectable *)dmake_job_msg;
+	sigset_t newset;
+        sigset_t oldset;
+
+	AVO_BLOCK_INTERUPTS;
+	int xdrResult = xdr(&xdrs_out, doJobMsg);
+
+	if (xdrResult) {
+		fflush(dmake_ofp);
+		AVO_UNBLOCK_INTERUPTS;
+	} else {
+		AVO_UNBLOCK_INTERUPTS;
+		fatal(catgets(catd, 1, 249, "Couldn't send the job request to rxm"));
+	}
+
+	delete dmake_job_msg;
+}
+
+// Queue for JobResult messages.
+static RWSlistCollectablesQueue jobResultQueue;
+
+// Queue for Acknowledge messages.
+static RWSlistCollectablesQueue acknowledgeQueue;
+
+// Read a message from the rxm process, and put it into a queue, by
+// message type. Return the message type.
+
+int
+getRxmMessage(void)
+{
+        RWCollectable	*msg = (RWCollectable *)0;
+	int		msgType = 0;
+//	sigset_t	newset;
+//	sigset_t	oldset;
+
+	// It seems unnecessarily to block interrupts here because
+	// any nonignored signal means exit for dmake in distributed mode.
+//	AVO_BLOCK_INTERUPTS;
+	int xdrResult = xdr(&xdrs_in, msg);
+//	AVO_UNBLOCK_INTERUPTS;
+
+	if (xdrResult) {
+		switch(msg->isA()) {
+		case __AVO_ACKNOWLEDGEMSG:
+			acknowledgeQueue.append(msg);
+			msgType = __AVO_ACKNOWLEDGEMSG;
+			break;
+		case __AVO_JOBRESULTMSG:
+			jobResultQueue.append(msg);
+			msgType = __AVO_JOBRESULTMSG;
+			break;
+		default:
+			warning(catgets(catd, 1, 291, "Unknown message on rxm input fd"));
+			msgType = 0;
+			break;
+		}
+	} else {
+		if (errno == EINTR) {
+			fputs(NOCATGETS("dmake: Internal error: xdr() has been interrupted by a signal.\n"), stderr);
+		}
+		fatal(catgets(catd, 1, 250, "Couldn't receive message from rxm"));
+	}
+
+	return msgType;
+}
+
+// Get a JobResult message from it's queue, and
+// if the queue is empty, call the getRxmMessage() function until
+// a JobResult message shows.
+
+Avo_JobResultMsg *
+getJobResultMsg(void)
+{
+	RWCollectable *msg = 0;
+
+	if (!(msg = jobResultQueue.get())) {
+		while (getRxmMessage() != __AVO_JOBRESULTMSG);
+		msg = jobResultQueue.get();
+	}
+
+	return (Avo_JobResultMsg *)msg;
+}
+
+// Get an Acknowledge message from it's queue, and
+// if the queue is empty, call the getRxmMessage() function until
+// a Acknowledge message shows.
+
+Avo_AcknowledgeMsg *
+getAcknowledgeMsg(void)
+{
+	RWCollectable *msg = 0;
+
+	if (!(msg = acknowledgeQueue.get())) {
+		while (getRxmMessage() != __AVO_ACKNOWLEDGEMSG);
+		msg = acknowledgeQueue.get();
+	}
+
+	return (Avo_AcknowledgeMsg *)msg;
+}
+
+
+/*
+ * Doname
+ * await_dist(Boolean waitflg)
+ *
+ * Waits for distributed children to exit and finishes their processing.
+ * Rxm will send a msg down the pipe when a child is done.
+ *
+ */
+Doname
+await_dist(Boolean waitflg)
+{
+	Avo_JobResultMsg	*dmake_result_msg;
+	int			job_msg_id;
+	Doname			result = build_ok;
+	int			result_msg_cmd_status;
+	int			result_msg_job_status;
+	Running			rp;
+
+	while (!(dmake_result_msg = getJobResultMsg()));
+	job_msg_id = dmake_result_msg->getId();
+	result_msg_cmd_status = dmake_result_msg->getCmdStatus();
+	result_msg_job_status = dmake_result_msg->getJobStatus();
+
+	if (waitflg) {
+		result = (result_msg_cmd_status == 0) ? build_ok : build_failed;
+
+#ifdef PRINT_EXIT_STATUS
+		if (result == build_ok) {
+			warning(NOCATGETS("I'm in await_dist(), waitflg is true, and result is build_ok."));
+		} else {
+			warning(NOCATGETS("I'm in await_dist(), waitflg is true, and result is build_failed."));
+		}
+#endif
+
+	} else {
+		for (rp = running_list;
+		     (rp != NULL) && (job_msg_id != rp->job_msg_id);
+		     rp = rp->next) {
+		}
+		if (rp == NULL) {
+			fatal(catgets(catd, 1, 251, "Internal error: returned child job_msg_id not in running_list"));
+		} else {
+			/* XXX - This may not be correct! */
+			if (result_msg_job_status == RETURNED) {
+				rp->state = build_ok;
+			} else {
+				rp->state = (result_msg_cmd_status == 0) ? build_ok : build_failed;
+			}
+			result = rp->state;
+
+#ifdef PRINT_EXIT_STATUS
+			if (result == build_ok) {
+				warning(NOCATGETS("I'm in await_dist(), waitflg is false, and result is build_ok."));
+			} else {
+				warning(NOCATGETS("I'm in await_dist(), waitflg is false, and result is build_failed."));
+			}
+#endif
+
+		}
+		parallel_process_cnt--;
+	}
+	delete dmake_result_msg;
+	return result;
+}
+
+#endif
+
+
--- /dev/null	2015-05-20 11:04:07.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/common/dmake.cc	2015-05-20 11:04:07.668574958 -0400
@@ -0,0 +1,29 @@
+/*
+ * 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 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)dmake.cc 1.2 06/12/12
+ */
+
+#pragma	ident	"@(#)dmake.cc	1.2	06/12/12"
--- /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;
+}
--- /dev/null	2015-05-20 11:04:08.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/common/dosys.cc	2015-05-20 11:04:08.116711869 -0400
@@ -0,0 +1,174 @@
+/*
+ * 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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)dosys.cc 1.45 06/12/12
+ */
+
+#pragma	ident	"@(#)dosys.cc	1.45	06/12/12"
+
+/*
+ *	dosys.cc
+ *
+ *	Execute one commandline
+ */
+
+/*
+ * Included files
+ */
+#include <fcntl.h>		/* open() */
+#include <mk/defs.h>
+#include <mksh/dosys.h>		/* doshell(), doexec() */
+#include <mksh/misc.h>		/* getmem() */
+#include <sys/stat.h>		/* open() */
+#include <unistd.h>		/* getpid() */
+
+/*
+ * Defined macros
+ */
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+static	int		filter_file;
+static	char		*filter_file_name;
+
+/*
+ * File table of contents
+ */
+static	void		redirect_stderr(void);
+
+/*
+ *	dosys(command, ignore_error, call_make, silent_error, target)
+ *
+ *	Check if command string contains meta chars and dispatch to
+ *	the proper routine for executing one command line.
+ *
+ *	Return value:
+ *				Indicates if the command execution failed
+ *
+ *	Parameters:
+ *		command		The command to run
+ *		ignore_error	Should make abort when an error is seen?
+ *		call_make	Did command reference $(MAKE) ?
+ *		silent_error	Should error messages be suppressed for pmake?
+ *		target		Target we are building
+ *
+ *	Global variables used:
+ *		do_not_exec_rule Is -n on?
+ *		working_on_targets We started processing real targets
+ */
+Doname
+dosys(register Name command, register Boolean ignore_error, register Boolean call_make, Boolean silent_error, Boolean always_exec, Name target, Boolean redirect_out_err)
+{
+	timestruc_t		before;
+	register int		length = command->hash.length;
+	Wstring			wcb(command);
+	register wchar_t	*p = wcb.get_string();
+	register wchar_t	*q;
+	Doname			result;
+
+	/* Strip spaces from head of command string */
+	while (iswspace(*p)) {
+		p++, length--;
+	}
+	if (*p == (int) nul_char) {
+		return build_failed;
+	}
+	/* If we are faking it we just return */
+	if (do_not_exec_rule &&
+	    working_on_targets &&
+	    !call_make &&
+	    !always_exec) {
+		return build_ok;
+	}
+	/* no_action_was_taken is used to print special message */
+	no_action_was_taken = false;
+
+	/* Copy string to make it OK to write it. */
+	q = ALLOC_WC(length + 1);
+	(void) wscpy(q, p);
+	/* Write the state file iff this command uses make. */
+	if (call_make && command_changed) {
+		write_state_file(0, false);
+	}
+	make_state->stat.time = file_no_time;
+	(void)exists(make_state);
+	before = make_state->stat.time;
+	/*
+	 * Run command directly if it contains no shell meta chars,
+	 * else run it using the shell.
+	 */
+	if (await(ignore_error,
+		  silent_error,
+		  target,
+		  wcb.get_string(),
+                  command->meta ?
+	            doshell(q, ignore_error, redirect_out_err,
+			    stdout_file, stderr_file, 0) :
+	            doexec(q, ignore_error, redirect_out_err,
+		 	   stdout_file, stderr_file,
+	                   vroot_path, 0),
+	          send_mtool_msgs,
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+                  get_xdrs_ptr(),
+                  get_job_msg_id()
+#else
+                  NULL,
+                  -1
+#endif
+	          )) {
+		result = build_ok;
+	} else {
+		result = build_failed;
+	}
+	retmem(q);
+
+	if ((report_dependencies_level == 0) &&
+	    call_make) {
+		make_state->stat.time = file_no_time;
+		(void)exists(make_state);
+		if (before == make_state->stat.time) {
+			return result;
+		}
+		makefile_type = reading_statefile;
+		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;
+	}
+	return result;
+}
--- /dev/null	2015-05-20 11:04:08.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/common/files.cc	2015-05-20 11:04:08.308140095 -0400
@@ -0,0 +1,733 @@
+/*
+ * 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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)files.cc 1.37 06/12/12
+ */
+
+#pragma	ident	"@(#)files.cc	1.37	06/12/12"
+
+/*
+ *	files.c
+ *
+ *	Various file related routines:
+ *		Figure out if file exists
+ *		Wildcard resolution for directory reader
+ *		Directory reader
+ */
+
+
+/*
+ * Included files
+ */
+#if defined(SUN5_0) || defined(HP_UX)
+#include <dirent.h>		/* opendir() */
+#else
+#include <sys/dir.h>		/* opendir() */
+#endif
+#include <errno.h>		/* errno */
+#include <mk/defs.h>
+#include <mksh/macro.h>		/* getvar() */
+#include <mksh/misc.h>		/* get_prop(), append_prop() */
+#include <sys/stat.h>		/* lstat() */
+
+/*
+ * Defined macros
+ */
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+
+/*
+ * File table of contents
+ */
+extern	timestruc_t&	exists(register Name target);
+extern  void		set_target_stat(register Name target, struct stat buf);
+static	timestruc_t&	vpath_exists(register Name target);
+static	Name		enter_file_name(wchar_t *name_string, wchar_t *library);
+static	Boolean		star_match(register char *string, register char *pattern);
+static	Boolean		amatch(register wchar_t *string, register wchar_t *pattern);
+  
+/*
+ *	exists(target)
+ *
+ *	Figure out the timestamp for one target.
+ *
+ *	Return value:
+ *				The time the target was created
+ *
+ *	Parameters:
+ *		target		The target to check
+ *
+ *	Global variables used:
+ *		debug_level	Should we trace the stat call?
+ *		recursion_level	Used for tracing
+ *		vpath_defined	Was the variable VPATH defined in environment?
+ */
+timestruc_t&
+exists(register Name target)
+{
+	struct stat		buf;
+	register int		result;
+
+	/* We cache stat information. */
+	if (target->stat.time != file_no_time) {
+		return target->stat.time;
+	}
+
+	/*
+	 * If the target is a member, we have to extract the time
+	 * from the archive.
+	 */
+	if (target->is_member &&
+	    (get_prop(target->prop, member_prop) != NULL)) {
+		return read_archive(target);
+	}
+
+	if (debug_level > 1) {
+		(void) printf(NOCATGETS("%*sstat(%s)\n"),
+		              recursion_level,
+		              "",
+		              target->string_mb);
+	}
+
+	result = lstat_vroot(target->string_mb, &buf, NULL, VROOT_DEFAULT);
+	if ((result != -1) && ((buf.st_mode & S_IFMT) == S_IFLNK)) {
+                /*
+		 * If the file is a symbolic link, we remember that
+		 * and then we get the status for the refd file.
+		 */
+                target->stat.is_sym_link = true;
+                result = stat_vroot(target->string_mb, &buf, NULL, VROOT_DEFAULT);
+        } else {
+                target->stat.is_sym_link = false;
+	}
+
+	if (result < 0) {
+		target->stat.time = file_doesnt_exist;
+		target->stat.stat_errno = errno;
+		if ((errno == ENOENT) &&
+		    vpath_defined &&
+/* azv, fixing bug 1262942, VPATH works with a leaf name
+ * but not a directory name.
+ */
+		    (target->string_mb[0] != (int) slash_char) ) {
+/* BID_1214655 */
+/* azv */
+			vpath_exists(target);
+			// return vpath_exists(target);
+		}
+	} else {
+		/* Save all the information we need about the file */
+		target->stat.stat_errno = 0;
+		target->stat.is_file = true;
+		target->stat.mode = buf.st_mode & 0777;
+		target->stat.size = buf.st_size;
+		target->stat.is_dir =
+		  BOOLEAN((buf.st_mode & S_IFMT) == S_IFDIR);
+		if (target->stat.is_dir) {
+			target->stat.time = file_is_dir;
+		} else {
+			/* target->stat.time = buf.st_mtime; */
+/* BID_1129806 */
+/* vis@nbsp.nsk.su */
+#if defined(linux)
+			timestruc_t ttime = { buf.st_mtime, 0 };
+			target->stat.time = MAX(ttime, file_min_time);
+#else
+			target->stat.time = MAX(buf.st_mtim, file_min_time);
+#endif
+		}
+	}
+	if ((target->colon_splits > 0) &&
+	    (get_prop(target->prop, time_prop) == NULL)) {
+		append_prop(target, time_prop)->body.time.time =
+		  target->stat.time;
+	}
+	return target->stat.time;
+}
+
+/*
+ *	set_target_stat( target, buf)
+ *
+ *	Called by exists() to set some stat fields in the Name structure
+ *	to those read by the stat_vroot() call (from disk).
+ *
+ *	Parameters:
+ *		target		The target whose stat field is set
+ *		buf		stat values (on disk) of the file
+ *				represented by target.
+ */
+void
+set_target_stat(register Name target, struct stat buf)
+{
+	target->stat.stat_errno = 0;
+	target->stat.is_file = true;
+	target->stat.mode = buf.st_mode & 0777;
+	target->stat.size = buf.st_size;
+	target->stat.is_dir =
+	  BOOLEAN((buf.st_mode & S_IFMT) == S_IFDIR);
+	if (target->stat.is_dir) {
+		target->stat.time = file_is_dir;
+	} else {
+		/* target->stat.time = buf.st_mtime; */
+/* BID_1129806 */
+/* vis@nbsp.nsk.su */
+#if defined(linux)
+		timestruc_t ttime = { buf.st_mtime, 0 };
+		target->stat.time = ttime;
+#else
+		target->stat.time = MAX(buf.st_mtim, file_min_time);
+#endif
+	}
+}
+
+
+/*
+ *	vpath_exists(target)
+ *
+ *	Called if exists() discovers that there is a VPATH defined.
+ *	This function stats the VPATH translation of the target.
+ *
+ *	Return value:
+ *				The time the target was created
+ *
+ *	Parameters:
+ *		target		The target to check
+ *
+ *	Global variables used:
+ *		vpath_name	The Name "VPATH", used to get macro value
+ */
+static timestruc_t&
+vpath_exists(register Name target)
+{
+	wchar_t			*vpath;
+	wchar_t			file_name[MAXPATHLEN];
+	wchar_t			*name_p;
+	Name			alias;
+
+	/*
+	 * To avoid recursive search through VPATH when exists(alias) is called
+	 */
+	vpath_defined = false;
+
+	Wstring wcb(getvar(vpath_name));
+	Wstring wcb1(target);
+
+	vpath = wcb.get_string();
+
+	while (*vpath != (int) nul_char) {
+		name_p = file_name;
+		while ((*vpath != (int) colon_char) &&
+		       (*vpath != (int) nul_char)) {
+			*name_p++ = *vpath++;
+		}
+		*name_p++ = (int) slash_char;
+		(void) wscpy(name_p, wcb1.get_string());
+		alias = GETNAME(file_name, FIND_LENGTH);
+		if (exists(alias) != file_doesnt_exist) {
+			target->stat.is_file = true;
+			target->stat.mode = alias->stat.mode;
+			target->stat.size = alias->stat.size;
+			target->stat.is_dir = alias->stat.is_dir;
+			target->stat.time = alias->stat.time;
+			maybe_append_prop(target, vpath_alias_prop)->
+						body.vpath_alias.alias = alias;
+			target->has_vpath_alias_prop = true;
+			vpath_defined = true;
+			return alias->stat.time;
+		}
+		while ((*vpath != (int) nul_char) &&
+		       ((*vpath == (int) colon_char) || iswspace(*vpath))) {
+			vpath++;
+		}
+	}
+	/*
+	 * Restore vpath_defined
+	 */
+	vpath_defined = true;
+	return target->stat.time;
+}
+
+/*
+ *	read_dir(dir, pattern, line, library)
+ *
+ *	Used to enter the contents of directories into makes namespace.
+ *	Presence of a file is important when scanning for implicit rules.
+ *	read_dir() is also used to expand wildcards in dependency lists.
+ *
+ *	Return value:
+ *				Non-0 if we found files to match the pattern
+ *
+ *	Parameters:
+ *		dir		Path to the directory to read
+ *		pattern		Pattern for that files should match or NULL
+ *		line		When we scan using a pattern we enter files
+ *				we find as dependencies for this line
+ *		library		If we scan for "lib.a(<wildcard-member>)"
+ *
+ *	Global variables used:
+ *		debug_level	Should we trace the dir reading?
+ *		dot		The Name ".", compared against
+ *		sccs_dir_path	The path to the SCCS dir (from PROJECTDIR)
+ *		vpath_defined	Was the variable VPATH defined in environment?
+ *		vpath_name	The Name "VPATH", use to get macro value
+ */
+int
+read_dir(Name dir, wchar_t *pattern, Property line, wchar_t *library)
+{
+	wchar_t			file_name[MAXPATHLEN];
+	wchar_t			*file_name_p = file_name;
+	Name			file;
+	wchar_t			plain_file_name[MAXPATHLEN];
+	wchar_t			*plain_file_name_p;
+	Name			plain_file;
+	wchar_t			tmp_wcs_buffer[MAXPATHLEN];
+	DIR			*dir_fd;
+	int			m_local_dependency=0;
+#if defined(SUN5_0) || defined(HP_UX)
+#define d_fileno d_ino
+        register struct dirent  *dp;
+#else
+        register struct direct  *dp;
+#endif
+	wchar_t			*vpath = NULL;
+	wchar_t			*p;
+	int			result = 0;
+
+	if(dir->hash.length >= MAXPATHLEN) {
+		return 0;
+	}
+
+	Wstring wcb(dir);
+	Wstring vps;
+
+	/* A directory is only read once unless we need to expand wildcards. */
+	if (pattern == NULL) {
+		if (dir->has_read_dir) {
+			return 0;
+		}
+		dir->has_read_dir = true;
+	}
+	/* Check if VPATH is active and setup list if it is. */
+	if (vpath_defined && (dir == dot)) {
+		vps.init(getvar(vpath_name));
+		vpath = vps.get_string();
+	}
+
+	/*
+	 * Prepare the string where we build the full name of the
+	 * files in the directory.
+	 */
+	if ((dir->hash.length > 1) || (wcb.get_string()[0] != (int) period_char)) {
+		(void) wscpy(file_name, wcb.get_string());
+		MBSTOWCS(wcs_buffer, "/");
+		(void) wscat(file_name, wcs_buffer);
+		file_name_p = file_name + wslen(file_name);
+	}
+
+	/* Open the directory. */
+vpath_loop:
+	dir_fd = opendir(dir->string_mb);
+	if (dir_fd == NULL) {
+		return 0;
+	}
+
+	/* Read all the directory entries. */
+	while ((dp = readdir(dir_fd)) != NULL) {
+		/* We ignore "." and ".." */
+		if ((dp->d_fileno == 0) ||
+		    ((dp->d_name[0] == (int) period_char) &&
+		     ((dp->d_name[1] == 0) ||
+		      ((dp->d_name[1] == (int) period_char) &&
+		       (dp->d_name[2] == 0))))) {
+			continue;
+		}
+		/*
+		 * Build the full name of the file using whatever
+		 * path supplied to the function.
+		 */
+		MBSTOWCS(tmp_wcs_buffer, dp->d_name);
+		(void) wscpy(file_name_p, tmp_wcs_buffer);
+		file = enter_file_name(file_name, library);
+		if ((pattern != NULL) && amatch(tmp_wcs_buffer, pattern)) {
+			/*
+			 * If we are expanding a wildcard pattern, we
+			 * enter the file as a dependency for the target.
+			 */
+			if (debug_level > 0){
+				WCSTOMBS(mbs_buffer, pattern);
+				(void) printf(catgets(catd, 1, 231, "'%s: %s' due to %s expansion\n"),
+					      line->body.line.target->string_mb,
+					      file->string_mb,
+					      mbs_buffer);
+			}
+			enter_dependency(line, file, false);
+			result++;
+		} else {
+			/*
+			 * If the file has an SCCS/s. file,
+			 * we will detect that later on.
+			 */
+			file->stat.has_sccs = NO_SCCS;
+		/*
+		 * If this is an s. file, we also enter it as if it
+		 * existed in the plain directory.
+		 */
+		if ((dp->d_name[0] == 's') &&
+		    (dp->d_name[1] == (int) period_char)) {
+	
+			MBSTOWCS(tmp_wcs_buffer, dp->d_name + 2);
+			plain_file_name_p = plain_file_name;
+			(void) wscpy(plain_file_name_p, tmp_wcs_buffer);
+			plain_file = GETNAME(plain_file_name, FIND_LENGTH);
+			plain_file->stat.is_file = true;
+			plain_file->stat.has_sccs = HAS_SCCS;
+			/*
+			 * Enter the s. file as a dependency for the
+			 * plain file.
+			 */
+			maybe_append_prop(plain_file, sccs_prop)->
+			  body.sccs.file = file;
+			MBSTOWCS(tmp_wcs_buffer, dp->d_name + 2);
+			if ((pattern != NULL) &&
+			    amatch(tmp_wcs_buffer, pattern)) {
+				if (debug_level > 0) {
+					WCSTOMBS(mbs_buffer, pattern);
+					(void) printf(catgets(catd, 1, 232, "'%s: %s' due to %s expansion\n"),
+						      line->body.line.target->
+						      string_mb,
+						      plain_file->string_mb,
+						      mbs_buffer);
+				}
+				enter_dependency(line, plain_file, false);
+				result++;
+			}
+		}
+	      }
+	}
+	(void) closedir(dir_fd);
+	if ((vpath != NULL) && (*vpath != (int) nul_char)) {
+		while ((*vpath != (int) nul_char) &&
+		       (iswspace(*vpath) || (*vpath == (int) colon_char))) {
+			vpath++;
+		}
+		p = vpath;
+		while ((*vpath != (int) colon_char) &&
+		       (*vpath != (int) nul_char)) {
+			vpath++;
+		}
+		if (vpath > p) {
+			dir = GETNAME(p, vpath - p);
+			goto vpath_loop;
+		}
+	}
+/*
+ * look into SCCS directory only if it's not svr4. For svr4 dont do that.
+ */
+
+/*
+ * Now read the SCCS directory.
+ * Files in the SCSC directory are considered to be part of the set of
+ * files in the plain directory. They are also entered in their own right.
+ * Prepare the string where we build the true name of the SCCS files.
+ */
+	(void) wsncpy(plain_file_name,
+		      file_name,
+		      file_name_p - file_name);
+	plain_file_name[file_name_p - file_name] = 0;
+	plain_file_name_p = plain_file_name + wslen(plain_file_name);
+
+        if(!svr4) {
+
+	  if (sccs_dir_path != NULL) {
+		wchar_t		tmp_wchar;
+		wchar_t		path[MAXPATHLEN];
+		char		mb_path[MAXPATHLEN];
+
+		if (file_name_p - file_name > 0) {
+			tmp_wchar = *file_name_p;
+			*file_name_p = 0;
+			WCSTOMBS(mbs_buffer, file_name);
+			(void) sprintf(mb_path, NOCATGETS("%s/%s/SCCS"),
+				        sccs_dir_path,
+				        mbs_buffer);
+			*file_name_p = tmp_wchar;
+		} else {
+			(void) sprintf(mb_path, NOCATGETS("%s/SCCS"), sccs_dir_path);
+		}
+		MBSTOWCS(path, mb_path);
+		(void) wscpy(file_name, path);
+	  } else {
+		MBSTOWCS(wcs_buffer, NOCATGETS("SCCS"));
+		(void) wscpy(file_name_p, wcs_buffer);
+	  }
+	} else {
+		MBSTOWCS(wcs_buffer, NOCATGETS("."));
+		(void) wscpy(file_name_p, wcs_buffer);
+	}
+	/* Internalize the constructed SCCS dir name. */
+	(void) exists(dir = GETNAME(file_name, FIND_LENGTH));
+	/* Just give up if the directory file doesnt exist. */
+	if (!dir->stat.is_file) {
+		return result;
+	}
+	/* Open the directory. */
+	dir_fd = opendir(dir->string_mb);
+	if (dir_fd == NULL) {
+		return result;
+	}
+	MBSTOWCS(wcs_buffer, "/");
+	(void) wscat(file_name, wcs_buffer);
+	file_name_p = file_name + wslen(file_name);
+
+	while ((dp = readdir(dir_fd)) != NULL) {
+		if ((dp->d_fileno == 0) ||
+		    ((dp->d_name[0] == (int) period_char) &&
+		     ((dp->d_name[1] == 0) ||
+		      ((dp->d_name[1] == (int) period_char) &&
+		       (dp->d_name[2] == 0))))) {
+			continue;
+		}
+		/* Construct and internalize the true name of the SCCS file. */
+		MBSTOWCS(wcs_buffer, dp->d_name);
+		(void) wscpy(file_name_p, wcs_buffer);
+		file = GETNAME(file_name, FIND_LENGTH);
+		file->stat.is_file = true;
+		file->stat.has_sccs = NO_SCCS;
+		/*
+		 * If this is an s. file, we also enter it as if it
+		 * existed in the plain directory.
+		 */
+		if ((dp->d_name[0] == 's') &&
+		    (dp->d_name[1] == (int) period_char)) {
+	
+			MBSTOWCS(wcs_buffer, dp->d_name + 2);
+			(void) wscpy(plain_file_name_p, wcs_buffer);
+			plain_file = GETNAME(plain_file_name, FIND_LENGTH);
+			plain_file->stat.is_file = true;
+			plain_file->stat.has_sccs = HAS_SCCS;
+				/* if sccs dependency is already set,skip */
+			if(plain_file->prop) {
+				Property sprop = get_prop(plain_file->prop,sccs_prop);
+				if(sprop != NULL) {
+					if (sprop->body.sccs.file) {
+						goto try_pattern;
+					}
+				}
+			}
+
+			/*
+			 * Enter the s. file as a dependency for the
+			 * plain file.
+			 */
+			maybe_append_prop(plain_file, sccs_prop)->
+			  body.sccs.file = file;
+try_pattern:
+			MBSTOWCS(tmp_wcs_buffer, dp->d_name + 2);
+			if ((pattern != NULL) &&
+			    amatch(tmp_wcs_buffer, pattern)) {
+				if (debug_level > 0) {
+					WCSTOMBS(mbs_buffer, pattern);
+					(void) printf(catgets(catd, 1, 233, "'%s: %s' due to %s expansion\n"),
+						      line->body.line.target->
+						      string_mb,
+						      plain_file->string_mb,
+						      mbs_buffer);
+				}
+				enter_dependency(line, plain_file, false);
+				result++;
+			}
+		}
+	}
+	(void) closedir(dir_fd);
+
+	return result;
+}
+
+/*
+ *	enter_file_name(name_string, library)
+ *
+ *	Helper function for read_dir().
+ *
+ *	Return value:
+ *				The Name that was entered
+ *
+ *	Parameters:
+ *		name_string	Name of the file we want to enter
+ *		library		The library it is a member of, if any
+ *
+ *	Global variables used:
+ */
+static Name
+enter_file_name(wchar_t *name_string, wchar_t *library)
+{
+	wchar_t		buffer[STRING_BUFFER_LENGTH];
+	String_rec	lib_name;
+	Name		name;
+	Property	prop;
+
+	if (library == NULL) {
+		name = GETNAME(name_string, FIND_LENGTH);
+		name->stat.is_file = true;
+		return name;
+	}
+
+	INIT_STRING_FROM_STACK(lib_name, buffer);
+	append_string(library, &lib_name, FIND_LENGTH);
+	append_char((int) parenleft_char, &lib_name);
+	append_string(name_string, &lib_name, FIND_LENGTH);
+	append_char((int) parenright_char, &lib_name);
+
+	name = GETNAME(lib_name.buffer.start, FIND_LENGTH);
+	name->stat.is_file = true;
+	name->is_member = true;
+	prop = maybe_append_prop(name, member_prop);
+	prop->body.member.library = GETNAME(library, FIND_LENGTH);
+	prop->body.member.library->stat.is_file = true;
+	prop->body.member.entry = NULL;
+	prop->body.member.member = GETNAME(name_string, FIND_LENGTH);
+	prop->body.member.member->stat.is_file = true;
+	return name;
+}
+
+/*
+ *	star_match(string, pattern)
+ *
+ *	This is a regular shell type wildcard pattern matcher
+ *	It is used when xpanding wildcards in dependency lists
+ *
+ *	Return value:
+ *				Indication if the string matched the pattern
+ *
+ *	Parameters:
+ *		string		String to match
+ *		pattern		Pattern to match it against
+ *
+ *	Global variables used:
+ */
+static Boolean
+star_match(register wchar_t *string, register wchar_t *pattern)
+{
+	register int		pattern_ch;
+
+	switch (*pattern) {
+	case 0:
+		return succeeded;
+	case bracketleft_char:
+	case question_char:
+	case asterisk_char:
+		while (*string) {
+			if (amatch(string++, pattern)) {
+				return succeeded;
+			}
+		}
+		break;
+	default:
+		pattern_ch = (int) *pattern++;
+		while (*string) {
+			if ((*string++ == pattern_ch) &&
+			    amatch(string, pattern)) {
+				return succeeded;
+			}
+		}
+		break;
+	}
+	return failed;
+}
+
+/*
+ *	amatch(string, pattern)
+ *
+ *	Helper function for shell pattern matching
+ *
+ *	Return value:
+ *				Indication if the string matched the pattern
+ *
+ *	Parameters:
+ *		string		String to match
+ *		pattern		Pattern to match it against
+ *
+ *	Global variables used:
+ */
+static Boolean
+amatch(register wchar_t *string, register wchar_t *pattern)
+{
+	register long		lower_bound;
+	register long		string_ch;
+	register long		pattern_ch;
+	register int		k;
+
+top:
+	for (; 1; pattern++, string++) {
+		lower_bound = 017777777777;
+		string_ch = *string;
+		switch (pattern_ch = *pattern) {
+		case bracketleft_char:
+			k = 0;
+			while ((pattern_ch = *++pattern) != 0) {
+				switch (pattern_ch) {
+				case bracketright_char:
+					if (!k) {
+						return failed;
+					}
+					string++;
+					pattern++;
+					goto top;
+				case hyphen_char:
+					k |= (lower_bound <= string_ch) &&
+					     (string_ch <=
+					      (pattern_ch = pattern[1]));
+				default:
+					if (string_ch ==
+					    (lower_bound = pattern_ch)) {
+						k++;
+					}
+				}
+			}
+			return failed;
+		case asterisk_char:
+			return star_match(string, ++pattern);
+		case 0:
+			return BOOLEAN(!string_ch);
+		case question_char:
+			if (string_ch == 0) {
+				return failed;
+			}
+			break;
+		default:
+			if (pattern_ch != string_ch) {
+				return failed;
+			}
+			break;
+		}
+	}
+	/* NOTREACHED */
+}
+
--- /dev/null	2015-05-20 11:04:08.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/common/globals.cc	2015-05-20 11:04:08.508973336 -0400
@@ -0,0 +1,217 @@
+/*
+ * 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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)globals.cc 1.42 06/12/12
+ */
+
+#pragma	ident	"@(#)globals.cc	1.42	06/12/12"
+
+/*
+ *	globals.cc
+ *
+ *	This declares all global variables
+ */
+
+/*
+ * Included files
+ */
+#include <nl_types.h>
+#include <mk/defs.h>
+#include <sys/stat.h>
+
+/*
+ * Defined macros
+ */
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Global variables used by make only
+ */
+	FILE		*dependency_report_file;
+
+/*
+ * Global variables used by make
+ */
+	Boolean		allrules_read=false;
+	Name		posix_name;
+	Name		svr4_name;
+	Boolean		sdot_target;	/* used to identify s.m(/M)akefile */
+	Boolean		all_parallel;			/* TEAMWARE_MAKE_CMN */
+	Boolean		assign_done;
+	int foo;	
+	Boolean		build_failed_seen;
+#ifdef DISTRIBUTED
+	Boolean		building_serial;
+#endif
+	Name		built_last_make_run;
+	Name		c_at;
+#ifdef DISTRIBUTED
+	Boolean		called_make = false;
+#endif
+	Boolean		cleanup;
+	Boolean		close_report;
+	Boolean		command_changed;
+	Boolean		commands_done;
+	Chain		conditional_targets;
+	Name		conditionals;
+	Boolean		continue_after_error;		/* `-k' */
+	Property	current_line;
+	Name		current_make_version;
+	Name		current_target;
+	short		debug_level;
+	Cmd_line	default_rule;
+	Name		default_rule_name;
+	Name		default_target_to_build;
+	Name		dmake_group;
+	Name		dmake_max_jobs;
+	Name		dmake_mode;
+	DMake_mode	dmake_mode_type;
+	Name		dmake_output_mode;
+	DMake_output_mode	output_mode = txt1_mode;
+	Name		dmake_odir;
+	Name		dmake_rcfile;
+	Name		done;
+	Name		dot;
+	Name		dot_keep_state;
+	Name		dot_keep_state_file;
+	Name		empty_name;
+#if defined(HP_UX) ||  defined(linux)
+	int		exit_status;
+#endif
+	Boolean		fatal_in_progress;
+	int		file_number;
+#if 0
+	Boolean		filter_stderr;			/* `-X' */
+#endif
+	Name		force;
+	Name		ignore_name;
+	Boolean		ignore_errors;			/* `-i' */
+	Boolean		ignore_errors_all;		/* `-i' */
+	Name		init;
+	int		job_msg_id;
+	Boolean		keep_state;
+	Name		make_state;
+#ifdef TEAMWARE_MAKE_CMN
+	timestruc_t	make_state_before;
+#endif
+	Dependency	makefiles_used;
+	Name		makeflags;
+//	Boolean		make_state_locked; // Moved to lib/mksh
+	Name		make_version;
+	char		mbs_buffer2[(MAXPATHLEN * MB_LEN_MAX)];
+	char		*mbs_ptr;
+	char		*mbs_ptr2;
+	int		mtool_msgs_fd;
+	Boolean		depinfo_already_read = false;
+#ifdef NSE
+        Name		derived_src;
+	Boolean		nse;				/* NSE on */
+        Name            nse_backquote_seen;
+	char		nse_depinfo_lockfile[MAXPATHLEN];
+	Boolean		nse_depinfo_locked;
+        Boolean         nse_did_recursion;
+        Name            nse_shell_var_used;
+        Boolean         nse_watch_vars = false;
+	wchar_t		current_makefile[MAXPATHLEN];
+#endif
+	Boolean		no_action_was_taken = true;	/* true if we've not **
+							** run any command   */
+
+	Boolean		no_parallel = false;		/* TEAMWARE_MAKE_CMN */
+#ifdef SGE_SUPPORT
+	Boolean		grid = false;			/* TEAMWARE_MAKE_CMN */
+#endif
+	Name		no_parallel_name;
+	Name		not_auto;
+	Boolean		only_parallel;			/* TEAMWARE_MAKE_CMN */
+	Boolean		parallel;			/* TEAMWARE_MAKE_CMN */
+	Name		parallel_name;
+	Name		localhost_name;
+	int		parallel_process_cnt;
+	Percent		percent_list;
+	Dyntarget	dyntarget_list;
+	Name		plus;
+	Name		pmake_machinesfile;
+	Name		precious;
+        Name		primary_makefile;
+	Boolean		quest;				/* `-q' */
+	short		read_trace_level;
+        Boolean 	reading_dependencies = false;
+	Name		recursive_name;
+	int		recursion_level;
+	short		report_dependencies_level = 0;	/* -P */
+	Boolean		report_pwd;
+	Boolean		rewrite_statefile;
+	Running		running_list;
+	char		*sccs_dir_path;
+	Name		sccs_get_name;
+	Name		sccs_get_posix_name;
+	Cmd_line	sccs_get_rule;
+	Cmd_line	sccs_get_org_rule;
+	Cmd_line	sccs_get_posix_rule;
+	Name		get_name;
+	Cmd_line	get_rule;
+	Name		get_posix_name;
+	Cmd_line	get_posix_rule;
+	Boolean		send_mtool_msgs;		/* `-K' */
+	Boolean		all_precious;
+	Boolean		silent_all;			/* `-s' */
+	Boolean		report_cwd;			/* `-w' */
+	Boolean		silent;				/* `-s' */
+	Name		silent_name;
+	char		*stderr_file = NULL;
+	char		*stdout_file = NULL;
+#ifdef SGE_SUPPORT
+	char		script_file[MAXPATHLEN] = "";
+#endif
+	Boolean		stdout_stderr_same;
+	Dependency	suffixes;
+	Name		suffixes_name;
+	Name		sunpro_dependencies;
+        Boolean		target_variants;
+	char		*tmpdir = NOCATGETS("/tmp");
+	char		*temp_file_directory = NOCATGETS(".");
+	Name		temp_file_name;
+	short		temp_file_number;
+	time_t		timing_start;
+	wchar_t		*top_level_target;
+	Boolean		touch;				/* `-t' */
+	Boolean		trace_reader;			/* `-D' */
+	Boolean		build_unconditional;		/* `-u' */
+	pathpt		vroot_path = VROOT_DEFAULT;
+	Name		wait_name;
+	wchar_t		wcs_buffer2[MAXPATHLEN];
+	wchar_t		*wcs_ptr;
+	wchar_t		*wcs_ptr2;
+	nl_catd		catd;
+	long int	hostid;
+
+/*
+ * File table of contents
+ */
+
--- /dev/null	2015-05-20 11:04:08.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/common/implicit.cc	2015-05-20 11:04:08.711716780 -0400
@@ -0,0 +1,1479 @@
+/*
+ * 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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)implicit.cc 1.64 06/12/12
+ */
+
+#pragma	ident	"@(#)implicit.cc	1.64	06/12/12"
+
+/*
+ *	implicit.c
+ *
+ *	Handle suffix and percent rules
+ */
+
+/*
+ * Included files
+ */
+#include <mk/defs.h>
+#include <mksh/macro.h>		/* expand_value() */
+#include <mksh/misc.h>		/* retmem() */
+
+/*
+ * Defined macros
+ */
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+static	wchar_t		WIDE_NULL[1] = {(wchar_t) nul_char};
+
+/*
+ * File table of contents
+ */
+extern	Doname		find_suffix_rule(Name target, Name target_body, Name target_suffix, Property *command, Boolean rechecking);
+extern	Doname		find_ar_suffix_rule(register Name target, Name true_target, Property *command, Boolean rechecking);
+extern	Doname		find_double_suffix_rule(register Name target, Property *command, Boolean rechecking);
+extern	void		build_suffix_list(register Name target_suffix);
+extern	Doname		find_percent_rule(register Name target, Property *command, Boolean rechecking);
+static	void 		create_target_group_and_dependencies_list(Name target, Percent pat_rule, String percent);
+static	Boolean		match_found_with_pattern(Name target, Percent pat_rule, String percent, wchar_t *percent_buf);
+static	void		construct_string_from_pattern(Percent pat_rule, String percent, String result);
+static	Boolean		dependency_exists(Name target, Property line);
+extern	Property	maybe_append_prop(Name, Property_id);
+extern	void		add_target_to_chain(Name target, Chain * query);
+
+/*
+ *	find_suffix_rule(target, target_body, target_suffix, command, rechecking)
+ * 
+ *	Does the lookup for single and double suffix rules.
+ *	It calls build_suffix_list() to build the list of possible suffixes
+ *	for the given target.
+ *	It then scans the list to find the first possible source file that
+ *	exists. This is done by concatenating the body of the target name
+ *	(target name less target suffix) and the source suffix and checking
+ *	if the resulting file exists.
+ *
+ *	Return value:
+ *				Indicates if search failed or not
+ *
+ *	Parameters:
+ *		target		The target we need a rule for
+ *		target_body	The target name without the suffix
+ *		target_suffix	The suffix of the target
+ *		command		Pointer to slot to deposit cmd in if found
+ *		rechecking	true if we are rechecking target which depends
+ *				on conditional macro and keep_state is set
+ *
+ *	Global variables used:
+ *		debug_level	Indicates how much tracing to do
+ *		recursion_level	Used for tracing
+ */
+
+extern int printf (const char *, ...);
+
+static Boolean actual_doname = false;
+
+/* /tolik/
+ * fix bug 1247448: Suffix Rules failed when combine with Pattern Matching Rules.
+ * When make attemps to apply % rule it didn't look for a single suffix rule because
+ * if "doname" is called from "find_percent_rule" argument "implicit" is set to true
+ * and find_suffix_rule was not called. I've commented the checking of "implicit"
+ * in "doname" and make got infinite recursion for SVR4 tilde rules.
+ * Usage of "we_are_in_tilde" is intended to avoid this recursion.
+ */
+
+static Boolean we_are_in_tilde = false; 
+
+Doname
+find_suffix_rule(Name target, Name target_body, Name target_suffix, Property *command, Boolean rechecking)
+{
+	static wchar_t		static_string_buf_3M [ 3 * MAXPATHLEN ];
+	Name			true_target = target;
+	wchar_t			*sourcename = (wchar_t*)static_string_buf_3M;
+	register wchar_t	*put_suffix;
+	register Property	source_suffix;
+	register Name		source;
+	Doname			result;
+	register Property	line;
+	extern Boolean 		tilde_rule;
+	Boolean 		name_found = true;
+	Boolean 		posix_tilde_attempt = true;
+	int			src_len = MAXPATHLEN + strlen(target_body->string_mb);
+
+	/*
+	 * To avoid infinite recursion
+	 */
+	if(we_are_in_tilde) {
+		we_are_in_tilde = false;
+		return(build_dont_know);
+	}
+
+	/*
+	 * 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 (debug_level > 1) {
+		(void) printf(NOCATGETS("%*sfind_suffix_rule(%s,%s,%s)\n"),
+			      recursion_level,
+			      "",
+			      true_target->string_mb,
+			      target_body->string_mb,
+			      target_suffix->string_mb);
+	}
+	if (command != NULL) {
+		if ((true_target->suffix_scan_done == true) && (*command == NULL)) {
+			return build_ok;
+		}
+	}
+	true_target->suffix_scan_done = true;
+	/*
+	 * Enter all names from the directory where the target lives as
+	 * files that makes sense.
+	 * This will make finding the synthesized source possible.
+	 */
+	read_directory_of_file(target_body);
+	/* Cache the suffixes for this target suffix if not done. */
+	if (!target_suffix->has_read_suffixes) {
+		build_suffix_list(target_suffix);
+	}
+	/* Preload the sourcename vector with the head of the target name. */
+	if (src_len >= sizeof(static_string_buf_3M)) {
+		sourcename = ALLOC_WC(src_len);
+	}
+	(void) mbstowcs(sourcename,
+		      target_body->string_mb,
+		      (int) target_body->hash.length);
+	put_suffix = sourcename + target_body->hash.length;
+	/* Scan the suffix list for the target if one exists. */
+	if (target_suffix->has_suffixes) {
+posix_attempts:
+		for (source_suffix = get_prop(target_suffix->prop,
+					      suffix_prop);
+		     source_suffix != NULL;
+		     source_suffix = get_prop(source_suffix->next,
+					      suffix_prop)) {
+			/* Build the synthesized source name. */
+			(void) mbstowcs(put_suffix,
+				      source_suffix->body.
+				      suffix.suffix->string_mb,
+				      (int) source_suffix->body.
+				      suffix.suffix->hash.length);
+			put_suffix[source_suffix->body.
+				   suffix.suffix->hash.length] =
+			  (int) nul_char;
+			if (debug_level > 1) {
+				WCSTOMBS(mbs_buffer, sourcename);
+				(void) printf(catgets(catd, 1, 218, "%*sTrying %s\n"),
+					      recursion_level,
+					      "",
+					      mbs_buffer);
+			}
+			source = getname_fn(sourcename, FIND_LENGTH, false, &name_found);
+			/*
+			 * If the source file is not registered as
+			 * a file, this source suffix did not match.
+			 */
+			if(vpath_defined && !posix && !svr4) {
+				(void) exists(source);	
+			}
+			if (!source->stat.is_file) {
+			   if(!(posix|svr4))
+			   {
+				if(!name_found) {
+					free_name(source);
+				}
+				continue;
+			   }
+
+			   /* following code will ensure that the corresponding
+			   ** tilde rules are executed when corresponding s. file
+			   ** exists in the current directory. Though the current
+			   ** target ends with a ~ character, there wont be any
+			   ** any file in the current directory with that suffix
+			   ** as it's fictitious. Even if it exists, it'll
+			   ** execute all the rules for the ~ target.
+			   */
+
+			   if(source->string_mb[source->hash.length - 1] == '~' &&
+			      ( svr4 || posix_tilde_attempt ) )
+			   {
+				char *p, *np; 
+				char *tmpbuf;
+
+				tmpbuf = getmem(source->hash.length + 8); 
+				/* + 8 to add "s." or "SCCS/s." */
+			        memset(tmpbuf,0,source->hash.length + 8);
+			        source->string_mb[source->hash.length - 1] = '\0';
+			        if(p = (char *) memchr((char *)source->string_mb,'/',source->hash.length)) 
+				{
+			          while(1) {  	
+				    if(np = (char *) memchr((char *)p+1,'/',source->hash.length - (p - source->string_mb))) {
+			              p = np;
+			            } else {break;}
+			          }
+				  /* copy everything including '/' */
+				  strncpy(tmpbuf, source->string_mb, p - source->string_mb + 1);
+				  strcat(tmpbuf, NOCATGETS("s."));
+				  strcat(tmpbuf, p+1);
+				  retmem((wchar_t *) source->string_mb); 
+				  source->string_mb = tmpbuf;
+				
+			        } else {
+				  strcpy(tmpbuf, NOCATGETS("s."));
+				  strcat(tmpbuf, source->string_mb);
+				  retmem((wchar_t *) source->string_mb); 
+				  source->string_mb = tmpbuf;
+				
+			        }
+				source->hash.length = strlen(source->string_mb);
+				if(exists(source) == file_doesnt_exist)
+				  continue;
+				tilde_rule = true;
+				we_are_in_tilde = true;
+			   } else {
+				if(!name_found) {
+					free_name(source);
+				}
+				continue;
+			   }
+			} else {
+			   if(posix && posix_tilde_attempt) {
+				if(exists(source) == file_doesnt_exist) {
+					if(!name_found) {
+						free_name(source);
+					}
+					continue;
+				}
+			   } 
+			}
+			
+			if (command != NULL) {
+				if(!name_found) {
+					store_name(source);
+				}
+				/*
+				 * The source file is a file.
+				 * Make sure it is up to date.
+				 */
+				if (dependency_exists(source,
+						      get_prop(target->prop,
+							       line_prop))) {
+					result = (Doname) source->state;
+				} else {
+#ifdef NSE
+		                        nse_check_derived_src(target, source->string,
+		                         source_suffix->body.suffix.command_template);
+#endif
+#if 0  /* with_squiggle sends false, which is buggy. : djay */
+					result = doname(source,
+							(Boolean) source_suffix->body.
+							suffix.suffix->with_squiggle,
+							true);
+#else
+					result = doname(source,
+							true,
+							true);
+#endif
+				}	
+			} else {
+				result = target_can_be_built(source);
+				
+				if (result == build_ok) {
+					return result;
+				} else {
+					if(!name_found) {
+						free_name(source);
+					}
+					continue;
+				}
+			}
+			
+			switch (result) {
+			case build_dont_know:
+				/*
+				 * If we still can't build the source,
+				 * this rule is not a match,
+				 * try the next one.
+				 */
+				if (source->stat.time == file_doesnt_exist) {
+					if(!name_found) {
+						free_name(source);
+					}
+					continue;
+				}
+			case build_running:
+				if(!name_found) {
+					store_name(source);
+				}
+				true_target->suffix_scan_done = false;
+				line = maybe_append_prop(target, line_prop);
+				enter_dependency(line, source, false);
+				line->body.line.target = true_target;
+				return build_running;
+			case build_ok:
+				if(!name_found) {
+					store_name(source);
+				}
+				break;
+			case build_failed:
+				if(!name_found) {
+					store_name(source);
+				}
+				if (sourcename != static_string_buf_3M) {
+					retmem(sourcename);
+				}
+				return build_failed;
+			}
+			
+			if (debug_level > 1) {
+				WCSTOMBS(mbs_buffer, sourcename);
+				(void) printf(catgets(catd, 1, 219, "%*sFound %s\n"),
+					      recursion_level,
+					      "",
+					      mbs_buffer);
+			}
+			
+			if (source->depends_on_conditional) {
+				target->depends_on_conditional = true;
+			}
+/*
+ * Since it is possible that the same target is built several times during
+ * the make run, we have to patch the target with all information we found
+ * here. Thus, the target will have an explicit rule the next time around.
+ */
+			line = maybe_append_prop(target, line_prop);
+			if (*command == NULL) {
+				*command = line;
+			}
+			if ((source->stat.time > (*command)->body.line.dependency_time) &&
+			    (debug_level > 1)) {
+				(void) printf(catgets(catd, 1, 220, "%*sDate(%s)=%s Date-dependencies(%s)=%s\n"),
+					      recursion_level,
+					      "",
+					      source->string_mb,
+					      time_to_string(source->
+							     stat.time),
+					      true_target->string_mb,
+					      time_to_string((*command)->
+							     body.line.
+							     dependency_time));
+			}
+			/*
+			 * Determine if this new dependency made the
+			 * target out of date.
+			 */
+			(*command)->body.line.dependency_time =
+			  MAX((*command)->body.line.dependency_time,
+			      source->stat.time);
+			Boolean out_of_date;
+			if (target->is_member) {
+				out_of_date = (Boolean) OUT_OF_DATE_SEC(target->stat.time,
+									(*command)->body.line.dependency_time);
+			} else {
+				out_of_date = (Boolean) OUT_OF_DATE(target->stat.time,
+								    (*command)->body.line.dependency_time);
+			}
+			if (build_unconditional || out_of_date) {
+				if(!rechecking) {
+					line->body.line.is_out_of_date = true;
+				}
+				if (debug_level > 0) {
+					(void) printf(catgets(catd, 1, 221, "%*sBuilding %s using suffix rule for %s%s because it is out of date relative to %s\n"),
+						      recursion_level,
+						      "",
+						      true_target->string_mb,
+						      source_suffix->body.suffix.suffix->string_mb,
+						      target_suffix->string_mb,
+						      source->string_mb);
+				}
+			}
+			/*
+			 * Add the implicit rule as the target's explicit
+			 * rule if none actually given, and register
+			 * dependency.
+			 * The time checking above really should be
+			 * conditional on actual use of implicit rule
+			 * as well.
+			 */
+			line->body.line.sccs_command = false;
+			if (line->body.line.command_template == NULL) {
+				line->body.line.command_template =
+				  source_suffix->body.suffix.command_template;
+			}
+			enter_dependency(line, source, false);
+			line->body.line.target = true_target;
+			/*
+			 * Also make sure the rule is built with
+			 * $* and $< bound properly.
+			 */
+			line->body.line.star = target_body;
+			if(svr4|posix) {
+			  char * p;
+			  char tstr[256];
+			  extern Boolean dollarless_flag;
+			  extern Name dollarless_value;
+
+			  if(tilde_rule) {
+			      MBSTOWCS(wcs_buffer, NOCATGETS(source->string_mb));
+			      dollarless_value = GETNAME(wcs_buffer,FIND_LENGTH);
+			  }
+			  else {
+				   dollarless_flag = false;
+			  }
+			}
+			line->body.line.less = source;
+			line->body.line.percent = NULL;
+			add_target_to_chain(source, &(line->body.line.query));
+			if (sourcename != static_string_buf_3M) {
+				retmem(sourcename);
+			}
+			return build_ok;
+		}
+		if(posix && posix_tilde_attempt) {
+			posix_tilde_attempt = false;
+			goto posix_attempts;
+		}
+		if ((command != NULL) &&
+		    ((*command) != NULL) &&
+		    ((*command)->body.line.star == NULL)) {
+			(*command)->body.line.star = target_body;
+		}
+	}
+	if (sourcename != static_string_buf_3M) {
+		retmem(sourcename);
+	}
+	/* Return here in case no rule matched the target */
+	return build_dont_know;
+}
+
+/*
+ *	find_ar_suffix_rule(target, true_target, command, rechecking)
+ *
+ *	Scans the .SUFFIXES list and tries
+ *	to find a suffix on it that matches the tail of the target member name.
+ *	If it finds a matching suffix it calls find_suffix_rule() to find
+ *	a rule for the target using the suffix ".a".
+ *
+ *	Return value:
+ *				Indicates if search failed or not
+ *
+ *	Parameters:
+ *		target		The target we need a rule for
+ *		true_target	The proper name
+ *		command		Pointer to slot where we stuff cmd, if found
+ *		rechecking	true if we are rechecking target which depends
+ *				on conditional macro and keep_state is set
+ *
+ *	Global variables used:
+ *		debug_level	Indicates how much tracing to do
+ *		dot_a		The Name ".a", compared against
+ *		recursion_level	Used for tracing
+ *		suffixes	List of suffixes used for scan (from .SUFFIXES)
+ */
+Doname
+find_ar_suffix_rule(register Name target, Name true_target, Property *command, Boolean rechecking)
+{
+	wchar_t			*target_end;
+	register Dependency	suffix;
+	register int		suffix_length;
+	Property		line;
+	Name			body;
+	static Name		dot_a;
+
+	Wstring			targ_string(true_target);
+	Wstring			suf_string;
+
+	if (dot_a == NULL) {
+		MBSTOWCS(wcs_buffer, NOCATGETS(".a"));
+		dot_a = GETNAME(wcs_buffer, FIND_LENGTH);
+	}
+	target_end = targ_string.get_string() + true_target->hash.length;
+
+	/*
+	 * We compare the tail of the target name with the suffixes
+	 * from .SUFFIXES.
+	 */
+	if (debug_level > 1) {
+		(void) printf(NOCATGETS("%*sfind_ar_suffix_rule(%s)\n"),
+			      recursion_level,
+			      "",
+			      true_target->string_mb);
+	}
+	/*
+	 * Scan the .SUFFIXES list to see if the target matches any of
+	 * those suffixes.
+	 */
+	for (suffix = suffixes; suffix != NULL; suffix = suffix->next) {
+		/* Compare one suffix. */
+		suffix_length = suffix->name->hash.length;
+		suf_string.init(suffix->name);
+		if (!IS_WEQUALN(suf_string.get_string(),
+			        target_end - suffix_length,
+			        suffix_length)) {
+			goto not_this_one;
+		}
+		/*
+		 * The target tail matched a suffix from the .SUFFIXES list.
+		 * Now check for a rule to match.
+		 */
+		target->suffix_scan_done = false;
+		body = GETNAME(targ_string.get_string(),
+  			       (int)(true_target->hash.length -
+				     suffix_length));
+		we_are_in_tilde = false;
+		switch (find_suffix_rule(target,
+					 body,
+					 dot_a,
+					 command,
+					 rechecking)) {
+		case build_ok:
+			line = get_prop(target->prop, line_prop);
+			line->body.line.star = body;
+			return build_ok;
+		case build_running:
+			return build_running;
+		}
+		/*
+		 * If no rule was found, we try the next suffix to see
+		 * if it matches the target tail, and so on.
+		 * Go here if the suffix did not match the target tail.
+		 */
+	not_this_one:;			 
+	}
+	return build_dont_know;
+}
+
+/*
+ *	find_double_suffix_rule(target, command, rechecking)
+ *
+ *	Scans the .SUFFIXES list and tries
+ *	to find a suffix on it that matches the tail of the target name.
+ *	If it finds a matching suffix it calls find_suffix_rule() to find
+ *	a rule for the target.
+ *
+ *	Return value:
+ *				Indicates if scan failed or not
+ *
+ *	Parameters:
+ *		target		Target we need a rule for
+ *		command		Pointer to slot where we stuff cmd, if found
+ *		rechecking	true if we are rechecking target which depends
+ *				on conditional macro and keep_state is set
+ *
+ *	Global variables used:
+ *		debug_level	Indicates how much tracing to do
+ *		recursion_level	Used for tracing
+ *		suffixes	List of suffixes used for scan (from .SUFFIXES)
+ */
+Doname
+find_double_suffix_rule(register Name target, Property *command, Boolean rechecking)
+{
+	Name			true_target = target;
+	Name			target_body;
+	register wchar_t	*target_end;
+	register Dependency	suffix;
+	register int		suffix_length;
+	Boolean			scanned_once = false;
+	Boolean			name_found = true;
+
+	Wstring			targ_string;
+	Wstring			suf_string;
+
+	/*
+	 * 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;
+	}
+	targ_string.init(true_target);
+
+	/*
+	 * We compare the tail of the target name with the
+	 * suffixes from .SUFFIXES.
+	 */
+	target_end = targ_string.get_string() + true_target->hash.length;
+	if (debug_level > 1) {
+		(void) printf(NOCATGETS("%*sfind_double_suffix_rule(%s)\n"),
+			      recursion_level,
+			      "",
+			      true_target->string_mb);
+	}
+	/*
+	 * Scan the .SUFFIXES list to see if the target matches
+	 * any of those suffixes.
+	 */
+	for (suffix = suffixes; suffix != NULL; suffix = suffix->next) {
+		target->suffix_scan_done = false;
+		true_target->suffix_scan_done = false;
+		/* Compare one suffix. */
+		suffix_length = suffix->name->hash.length;
+		suf_string.init(suffix->name);
+		/* Check the lengths, or else RTC will report rua. */
+		if (true_target->hash.length < suffix_length) {
+			goto not_this_one;
+		} else if (!IS_WEQUALN(suf_string.get_string(),
+			        (target_end - suffix_length),
+			        suffix_length)) {
+			goto not_this_one;
+		}
+		/*
+		 * The target tail matched a suffix from the .SUFFIXES list.
+		 * Now check for a rule to match.
+		 */
+		we_are_in_tilde = false;
+		target_body = GETNAME(
+			targ_string.get_string(),
+			(int)(true_target->hash.length - suffix_length)
+		);
+		switch (find_suffix_rule(target,
+					 target_body,
+					 suffix->name,
+					 command,
+					 rechecking)) {
+		case build_ok:
+			return build_ok;
+		case build_running:
+			return build_running;
+		}
+		if (true_target->suffix_scan_done == true) {
+			scanned_once = true;
+		}
+		/*
+		 * If no rule was found, we try the next suffix to see
+		 * if it matches the target tail. And so on.
+		 * Go here if the suffix did not match the target tail.
+		 */
+	not_this_one:;			 
+	}
+	if (scanned_once)
+		true_target->suffix_scan_done = true;
+	return build_dont_know;
+}
+
+/*
+ *	build_suffix_list(target_suffix)
+ *
+ *	Scans the .SUFFIXES list and figures out
+ *	which suffixes this target can be derived from.
+ *	The target itself is not know here, we just know the suffix of the
+ *	target. For each suffix on the list the target can be derived iff
+ *	a rule exists for the name "<suffix-on-list><target-suffix>".
+ *	A list of all possible building suffixes is built, with the rule for
+ *	each, and tacked to the target suffix nameblock.
+ *
+ *	Parameters:
+ *		target_suffix	The suffix we build a match list for
+ *
+ *	Global variables used:
+ *		debug_level	Indicates how much tracing to do
+ *		recursion_level	Used for tracing
+ *		suffixes	List of suffixes used for scan (from .SUFFIXES)
+ *		working_on_targets Indicates that this is a real target
+ */
+void
+build_suffix_list(register Name target_suffix)
+{
+	register Dependency	source_suffix;
+	wchar_t			rule_name[MAXPATHLEN];
+	register Property	line;
+	register Property	suffix;
+	Name			rule;
+
+	/* If this is before default.mk has been read we just return to try */
+	/* again later */
+	if ((suffixes == NULL) || !working_on_targets) {
+		return;
+	}
+	if (debug_level > 1) {
+		(void) printf(NOCATGETS("%*sbuild_suffix_list(%s) "),
+			      recursion_level,
+			      "",
+			      target_suffix->string_mb);
+	}
+	/* Mark the target suffix saying we cashed its list */
+	target_suffix->has_read_suffixes = true;
+	/* Scan the .SUFFIXES list */
+	for (source_suffix = suffixes;
+	     source_suffix != NULL;
+	     source_suffix = source_suffix->next) {
+		/*
+		 * Build the name "<suffix-on-list><target-suffix>".
+		 * (a popular one would be ".c.o").
+		 */
+		(void) mbstowcs(rule_name,
+			      source_suffix->name->string_mb,
+			      (int) source_suffix->name->hash.length);
+		(void) mbstowcs(rule_name + source_suffix->name->hash.length,
+			      target_suffix->string_mb,
+			      (int) target_suffix->hash.length);
+		/*
+		 * Check if that name has a rule. If not, it cannot match
+		 * any implicit rule scan and is ignored.
+		 * The GETNAME() call only checks for presence, it will not
+		 * enter the name if it is not defined.
+		 */
+		if (((rule = getname_fn(rule_name,
+					(int) (source_suffix->name->
+					       hash.length +
+					       target_suffix->hash.length),
+					true)) != NULL) &&
+		    ((line = get_prop(rule->prop, line_prop)) != NULL)) {
+			if (debug_level > 1) {
+				(void) printf("%s ", rule->string_mb);
+			}
+			/*
+			 * This makes it possible to quickly determine if
+			 * it will pay to look for a suffix property.
+			 */
+			target_suffix->has_suffixes = true;
+			/*
+			 * Add the suffix property to the target suffix
+			 * and save the rule with it.
+			 * All information the implicit rule scanner need
+			 * is saved in the suffix property.
+			 */
+			suffix = append_prop(target_suffix, suffix_prop);
+			suffix->body.suffix.suffix = source_suffix->name;
+			suffix->body.suffix.command_template =
+			  line->body.line.command_template;
+		}
+	}
+	if (debug_level > 1) {
+		(void) printf("\n");
+	}
+}
+
+/*
+ *	find_percent_rule(target, command, rechecking)
+ *
+ *	Tries to find a rule from the list of wildcard matched rules.
+ *	It scans the list attempting to match the target.
+ *	For each target match it checks if the corresponding source exists.
+ *	If it does the match is returned.
+ *	The percent_list is built at makefile read time.
+ *	Each percent rule get one entry on the list.
+ *
+ *	Return value:
+ *				Indicates if the scan failed or not
+ *
+ *	Parameters:
+ *		target		The target we need a rule for
+ *		command		Pointer to slot where we stuff cmd, if found
+ *		rechecking	true if we are rechecking target which depends
+ *				on conditional macro and keep_state is set
+ *
+ *	Global variables used:
+ *		debug_level	Indicates how much tracing to do
+ *		percent_list	List of all percent rules
+ *		recursion_level	Used for tracing
+ *		empty_name
+ */
+Doname
+find_percent_rule(register Name target, Property *command, Boolean rechecking)
+{
+	register Percent	pat_rule, pat_depe;
+	register Name		depe_to_check;
+	register Dependency	depe;
+	register Property	line;
+	String_rec		string;
+	wchar_t			string_buf[STRING_BUFFER_LENGTH];
+	String_rec		percent;
+	wchar_t			percent_buf[STRING_BUFFER_LENGTH];
+	Name			true_target = target;
+	Name			less;
+	Boolean			nonpattern_less;
+	Boolean			dep_name_found = false;
+	Doname			result = build_dont_know;
+	Percent			rule_candidate = NULL;
+	Boolean			rule_maybe_ok;
+	Boolean			is_pattern;
+
+	/* If the target is constructed for a "::" target we consider that */
+	if (target->has_target_prop) {
+		true_target = get_prop(target->prop,
+				       target_prop)->body.target.target;
+	}
+	if (target->has_long_member_name) {
+		true_target = get_prop(target->prop,
+				       long_member_name_prop)->body.long_member_name.member_name;
+	}
+	if (debug_level > 1) {
+		(void) printf(catgets(catd, 1, 222, "%*sLooking for %% rule for %s\n"),
+			      recursion_level,
+			      "",
+			      true_target->string_mb);
+	}
+	for (pat_rule = percent_list;
+	     pat_rule != NULL;
+	     pat_rule = pat_rule->next) {
+		/* Avoid infinite recursion when expanding patterns */
+		if (pat_rule->being_expanded == true) {
+			continue;
+		}
+
+		/* Mark this pat_rule as "maybe ok". If no % rule is found
+		   make will use this rule. The following algorithm is used:
+		   1) make scans all pattern rules in order to find the rule
+		      where ALL dependencies, including nonpattern ones, exist or
+		      can be built (GNU behaviour). If such rule is found make
+		      will apply it.
+		   2) During this check make also remembers the first pattern rule
+		      where all PATTERN dependencies can be build (no matter what
+		      happens with nonpattern dependencies).
+		   3) If no rule satisfying 1) is found, make will apply the rule
+		      remembered in 2) if there is one.
+		*/
+		rule_maybe_ok = true;
+
+		/* used to track first percent dependency */
+		less = NULL;
+		nonpattern_less = true;
+
+		/* check whether pattern matches.
+		   if it matches, percent string will contain matched percent part of pattern */
+		if (!match_found_with_pattern(true_target, pat_rule, &percent, percent_buf)) {
+			continue;
+		}
+		if (pat_rule->dependencies != NULL) {
+			for (pat_depe = pat_rule->dependencies;
+			     pat_depe != NULL;
+			     pat_depe = pat_depe->next) {
+				/* checking result for dependency */
+				result = build_dont_know;
+
+				dep_name_found = true;
+				if (pat_depe->name->percent) {
+					is_pattern = true;
+					/* build dependency name */
+					INIT_STRING_FROM_STACK(string, string_buf);
+					construct_string_from_pattern(pat_depe, &percent, &string); 
+					depe_to_check = getname_fn(string.buffer.start,
+						FIND_LENGTH,
+						false,
+						&dep_name_found
+					);
+
+					if ((less == NULL) || nonpattern_less) {
+						less = depe_to_check;
+						nonpattern_less = false;
+					}
+				} else {
+					/* nonpattern dependency */
+					is_pattern = false;
+					depe_to_check = pat_depe->name;
+					if(depe_to_check->dollar) {
+						INIT_STRING_FROM_STACK(string, string_buf);
+						expand_value(depe_to_check, &string, false);
+						depe_to_check = getname_fn(string.buffer.start,
+							FIND_LENGTH,
+							false,
+							&dep_name_found
+						);
+					}
+					if (less == NULL) {
+						less = depe_to_check;
+					}
+				}
+
+				if (depe_to_check == empty_name) {
+						result = build_ok;
+				} else {
+					if (debug_level > 1) {
+						(void) printf(catgets(catd, 1, 223, "%*sTrying %s\n"),
+							      recursion_level,
+							      "",
+							      depe_to_check->string_mb);
+					}
+
+					pat_rule->being_expanded = true;
+
+					/* suppress message output */
+					int save_debug_level = debug_level;
+					debug_level = 0;
+
+					/* check whether dependency can be built */
+					if (dependency_exists(depe_to_check,
+					      get_prop(target->prop,
+						       line_prop)))
+					{
+						result = (Doname) depe_to_check->state;
+					} else {
+						if(actual_doname) {
+							result = doname(depe_to_check, true, true);
+						} else {
+							result = target_can_be_built(depe_to_check);
+						}
+						if(!dep_name_found) {
+							if(result != build_ok && result != build_running) {
+								free_name(depe_to_check);
+							} else {
+								store_name(depe_to_check);
+							}
+						}
+					}
+					if(result != build_ok && is_pattern) {
+						rule_maybe_ok = false;
+					}
+
+					/* restore debug_level */
+					debug_level = save_debug_level;
+				}
+
+				if (pat_depe->name->percent) {
+					if (string.free_after_use) {
+						retmem(string.buffer.start);
+					}
+				}
+				/* make can't figure out how to make this dependency */
+				if (result != build_ok && result != build_running) {
+					pat_rule->being_expanded = false;
+					break;
+				}
+			}
+		} else {
+			result = build_ok;
+		}
+
+		/* this pattern rule is the needed one since all dependencies could be built */
+		if (result == build_ok || result == build_running) {
+			break;
+		}
+
+		/* Make does not know how to build some of dependencies from this rule.
+		   But if all "pattern" dependencies can be built, we remember this rule
+		   as a candidate for the case if no other pattern rule found.
+		*/
+		if(rule_maybe_ok && rule_candidate == NULL) {
+			rule_candidate = pat_rule;
+		}
+	}
+
+	/* if no pattern matching rule was found, use the remembered candidate
+	   or return build_dont_know if there is no candidate.
+	*/
+	if (result != build_ok && result != build_running) {
+		if(rule_candidate) {
+			pat_rule = rule_candidate;
+		} else {
+			return build_dont_know;
+		}
+	}
+
+	/* if we are performing only check whether dependency could be built with existing rules,
+	   return success */
+	if (command == NULL) {
+		if(pat_rule != NULL) {
+			pat_rule->being_expanded = false;
+		}
+		return result;
+	}
+
+	if (debug_level > 1) {
+		(void) printf(catgets(catd, 1, 224, "%*sMatched %s:"),
+				      recursion_level,
+				      "",
+				      target->string_mb);
+
+		for (pat_depe = pat_rule->dependencies;
+		     pat_depe != NULL;
+		     pat_depe = pat_depe->next) {
+			if (pat_depe->name->percent) {
+				INIT_STRING_FROM_STACK(string, string_buf);
+				construct_string_from_pattern(pat_depe, &percent, &string);
+				depe_to_check = GETNAME(string.buffer.start, FIND_LENGTH);
+			} else {
+				depe_to_check = pat_depe->name;
+				if(depe_to_check->dollar) {
+					INIT_STRING_FROM_STACK(string, string_buf);
+					expand_value(depe_to_check, &string, false);
+					depe_to_check = GETNAME(string.buffer.start, FIND_LENGTH);
+				}
+			}
+
+			if (depe_to_check != empty_name) {
+				(void) printf(" %s", depe_to_check->string_mb);
+			}
+		}
+
+		(void) printf(catgets(catd, 1, 225, " from: %s:"),
+			      pat_rule->name->string_mb);
+
+		for (pat_depe = pat_rule->dependencies;
+		     pat_depe != NULL;
+		     pat_depe = pat_depe->next) {
+			(void) printf(" %s", pat_depe->name->string_mb);
+		}
+
+		(void) printf("\n");
+	}
+
+	if (true_target->colons == no_colon) {
+		true_target->colons = one_colon;
+	}
+
+	/* create deppendency list and target group from matched pattern rule */
+	create_target_group_and_dependencies_list(target, pat_rule, &percent);
+
+	/* save command */
+	line = get_prop(target->prop, line_prop);
+	*command = line;
+
+	/* free query chain if one exist */
+	while(line->body.line.query != NULL) {
+		Chain to_free = line->body.line.query;
+		line->body.line.query = line->body.line.query->next;
+		retmem_mb((char *) to_free);
+	}
+
+	if (line->body.line.dependencies != NULL) {
+		/* build all collected dependencies */
+		for (depe = line->body.line.dependencies;
+		     depe != NULL; 
+		     depe = depe->next) {
+			actual_doname = true;
+			result = doname_check(depe->name, true, true, depe->automatic);
+
+			actual_doname = false;
+			if (result == build_failed) {
+				pat_rule->being_expanded = false;
+				return build_failed;
+			}
+			if (result == build_running) {
+				pat_rule->being_expanded = false;
+				return build_running;
+			}
+
+			if ((depe->name->stat.time > line->body.line.dependency_time) &&
+			    (debug_level > 1)) {
+				(void) printf(catgets(catd, 1, 226, "%*sDate(%s)=%s Date-dependencies(%s)=%s\n"),
+					      recursion_level,
+					      "",
+					      depe->name->string_mb,
+					      time_to_string(depe->name->stat.time),
+					      true_target->string_mb,
+					      time_to_string(line->body.line.dependency_time));
+			}
+
+			line->body.line.dependency_time =
+			  MAX(line->body.line.dependency_time, depe->name->stat.time);
+
+			/* determine whether this dependency made target out of date */
+			Boolean out_of_date;
+			if (target->is_member || depe->name->is_member) {
+				out_of_date = (Boolean) OUT_OF_DATE_SEC(target->stat.time, depe->name->stat.time);
+			} else {
+				out_of_date = (Boolean) OUT_OF_DATE(target->stat.time, depe->name->stat.time);
+			}
+			if (build_unconditional || out_of_date) {
+				if(!rechecking) {
+					line->body.line.is_out_of_date = true;
+				}
+				add_target_to_chain(depe->name, &(line->body.line.query));
+
+				if (debug_level > 0) {
+					(void) printf(catgets(catd, 1, 227, "%*sBuilding %s using pattern rule %s:"),
+						      recursion_level,
+						      "",
+						      true_target->string_mb,
+						      pat_rule->name->string_mb);
+
+					for (pat_depe = pat_rule->dependencies;
+					     pat_depe != NULL;
+					     pat_depe = pat_depe->next) {
+						(void) printf(" %s", pat_depe->name->string_mb);
+					}
+
+					(void) printf(catgets(catd, 1, 228, " because it is out of date relative to %s\n"), 
+						      depe->name->string_mb);
+				}	
+			}
+		}
+	} else {
+		if ((true_target->stat.time <= file_doesnt_exist) ||
+		    (true_target->stat.time < line->body.line.dependency_time)) {
+			if(!rechecking) {
+				line->body.line.is_out_of_date = true;
+			}
+			if (debug_level > 0) {
+				(void) printf(catgets(catd, 1, 229, "%*sBuilding %s using pattern rule %s: "),
+					      recursion_level,
+					      "",
+					      true_target->string_mb,
+					      pat_rule->name->string_mb,
+					      (target->stat.time > file_doesnt_exist) ?
+					      catgets(catd, 1, 230, "because it is out of date") :
+					      catgets(catd, 1, 236, "because it does not exist"));
+			}
+		}
+	}
+
+	/* enter explicit rule from percent rule */	
+	Name lmn_target = true_target;
+	if (true_target->has_long_member_name) {
+		lmn_target = get_prop(true_target->prop, long_member_name_prop)->body.long_member_name.member_name;
+	}
+	line->body.line.sccs_command = false;
+	line->body.line.target = true_target;
+	line->body.line.command_template = pat_rule->command_template;
+	line->body.line.star = GETNAME(percent.buffer.start, FIND_LENGTH);
+	line->body.line.less = less;
+
+	if (lmn_target->parenleft) {
+		Wstring lmn_string(lmn_target);
+
+		wchar_t *left = (wchar_t *) wschr(lmn_string.get_string(), (int) parenleft_char);
+		wchar_t *right = (wchar_t *) wschr(lmn_string.get_string(), (int) parenright_char);
+
+		if ((left == NULL) || (right == NULL)) {
+			line->body.line.percent = NULL;
+		} else {
+			line->body.line.percent = GETNAME(left + 1, right - left - 1);
+		}
+	} else {
+		line->body.line.percent = NULL;
+	}
+	pat_rule->being_expanded = false;
+
+#ifdef TEAMWARE_MAKE_CMN
+	/*
+	 * This #ifdef fixes a dmake bug, but introduces bugid 1136156.
+	 */
+	return result;
+#else
+	return build_ok;
+#endif
+}
+
+/*
+ *	match_found_with_pattern 
+ *           ( target, pat_rule, percent, percent_buf)
+ *	
+ *	matches "target->string" with a % pattern.
+ *	If pattern contains a MACRO definition, it's expanded first.
+ *
+ *	Return value:
+ *				true if a match was found
+ *
+ *	Parameters:
+ *		target		The target we're trying to match
+ *     		pattern		
+ *		percent		record that contains "percent_buf" below
+ *		percent_buf	This is where the patched % part of pattern is stored 
+ *
+ */
+
+static Boolean
+match_found_with_pattern(Name target, Percent pat_rule, String percent, wchar_t *percent_buf) {
+	String_rec		string;
+	wchar_t			string_buf[STRING_BUFFER_LENGTH];
+
+	/* construct prefix string and check whether prefix matches */
+	Name prefix = pat_rule->patterns[0];
+	int prefix_length;
+
+	Wstring targ_string(target);
+	Wstring pref_string(prefix);
+	Wstring suf_string;
+
+	if (prefix->dollar) {	
+		INIT_STRING_FROM_STACK(string, string_buf);
+		expand_value(prefix, &string, false);
+		prefix_length = string.text.p - string.buffer.start;
+		if ((string.buffer.start[0] == (int) period_char) &&
+		    (string.buffer.start[1] == (int) slash_char)) {
+			string.buffer.start += 2;
+			prefix_length -= 2;
+		}
+		if (!targ_string.equaln(string.buffer.start, prefix_length)) {
+			return false;
+		}
+	} else {
+		prefix_length = prefix->hash.length;
+		if (!targ_string.equaln(&pref_string, prefix_length)) {
+			return false;
+		}
+	}
+
+	/* do the same with pattern suffix */
+	Name suffix = pat_rule->patterns[pat_rule->patterns_total - 1];
+	suf_string.init(suffix);
+
+	int suffix_length;
+	if (suffix->dollar) {
+		INIT_STRING_FROM_STACK(string, string_buf);
+		expand_value(suffix, &string, false);
+		suffix_length = string.text.p - string.buffer.start;
+		if(suffix_length > target->hash.length) {
+			return false;
+		}
+		if (!targ_string.equal(string.buffer.start, target->hash.length - suffix_length)) {
+			return false;
+		}
+	} else {
+		suffix_length = (int) suffix->hash.length;
+		if(suffix_length > target->hash.length) {
+			return false;
+		}
+		if (!targ_string.equal(&suf_string, target->hash.length - suffix_length)) {
+			return false;
+		}
+	}
+
+	Boolean match_found = false;
+	int percent_length = target->hash.length - prefix_length - suffix_length;
+	
+	while (!match_found && (percent_length >= 0)) {
+		/* init result string */
+		INIT_STRING_FROM_STACK(string, string_buf);
+
+		/* init percent string */
+		percent->buffer.start = percent_buf;
+		percent->text.p = percent_buf;
+		percent->text.end = NULL;
+		percent->free_after_use = false;
+		percent->buffer.end = percent_buf + STRING_BUFFER_LENGTH;
+
+		/* construct percent and result strings */
+		targ_string.append_to_str(percent, prefix_length, percent_length);
+		construct_string_from_pattern(pat_rule, percent, &string);
+
+		/* check for match */
+		if (targ_string.equal(string.buffer.start, 0)) {
+			match_found = true;
+		} else {
+			percent_length--;
+		}
+	}
+	
+	/* result */
+	return match_found;
+}
+
+
+/*
+ *	create_target_group_and_dependencies_list
+ *           (target, pat_rule, percent)
+ *	
+ *	constructs dependency list and a target group from pattern.
+ *
+ *	If we have the lines
+ *		%/%.a + %/%.b + C%/CC%.c: yyy %.d bb%/BB%.e
+ *			commands
+ *
+ * 	and we have matched the pattern xx/xx.a with %/%.a, then we
+ *	construct a target group that looks like this:
+ *		xx/xx.a + xx/xx.b + Cxx/CCxx.c: dependencies
+ *
+ *	and construct dependency list that looks like this:
+ *	yyy xx.d bbxx/BBxx.e + already existed dependencies
+ *	
+ *	Return value:
+ *				none
+ *
+ *	Parameters:
+ *		target		The target we are building, in the previous
+ *				example, this is xx/xx.a
+ *     		pat_rule        the % pattern that matched "target", here %/%.a
+ *		percent		string containing matched % part. In the example=xx.
+ *
+ *	Global variables used:
+ *		empty_name
+ */
+
+static void
+create_target_group_and_dependencies_list(Name target, Percent pat_rule, String percent) {
+	String_rec	string;
+	wchar_t		string_buf[STRING_BUFFER_LENGTH];
+	Percent		pat_depe;
+	Name		depe;
+	Property	line = maybe_append_prop(target, line_prop);
+	Chain		new_target_group = NULL;
+	Chain		*new_target_group_tail = &new_target_group;
+	Chain		group_member;
+	
+	/* create and append dependencies from rule */
+	for (pat_depe = pat_rule->dependencies; pat_depe != NULL; pat_depe = pat_depe->next) {
+		if (pat_depe->name->percent) {
+			INIT_STRING_FROM_STACK(string, string_buf);
+			construct_string_from_pattern(pat_depe, percent, &string);
+			depe = GETNAME(string.buffer.start, FIND_LENGTH);
+			if (depe != empty_name) {
+				enter_dependency(line, depe, false);
+			}
+		} else {
+			depe = pat_depe->name;
+			if(depe->dollar) {
+				INIT_STRING_FROM_STACK(string, string_buf);
+				expand_value(depe, &string, false);
+				depe = GETNAME(string.buffer.start, FIND_LENGTH);
+			}
+			enter_dependency(line, depe, false);
+		}
+	}
+	
+	/* if matched pattern is a group member, create new target group */
+	for (group_member = pat_rule->target_group; group_member != NULL; group_member = group_member->next) {
+		Name new_target = group_member->name;
+		if (group_member->name->percent) {
+			INIT_STRING_FROM_STACK(string, string_buf);
+			construct_string_from_pattern(group_member->percent_member, percent, &string);
+			new_target = GETNAME(string.buffer.start, FIND_LENGTH);
+			if (new_target == empty_name) {
+				continue;
+			}
+		}
+
+		/* check for duplicates */
+		Chain	tgm;
+		for (tgm = new_target_group; tgm != NULL; tgm = tgm->next) {
+			if (new_target == tgm->name) {
+				break;
+			}
+		}
+		if (tgm != NULL) {
+			continue;
+		}
+		
+		/* insert it into the targets list */
+		(*new_target_group_tail) = ALLOC(Chain);
+		(*new_target_group_tail)->name = new_target;
+		(*new_target_group_tail)->next = NULL;
+		new_target_group_tail = &(*new_target_group_tail)->next;
+	}
+	
+	/* now we gathered all dependencies and created target group */
+	line->body.line.target_group = new_target_group;
+
+	/* update properties for group members */
+	for (group_member = new_target_group; group_member != NULL; group_member = group_member->next) {
+		if (group_member->name != target) {
+			group_member->name->prop = target->prop;
+			group_member->name->conditional_cnt = target->conditional_cnt;
+		}
+	}
+}
+
+/*
+ *	construct_string_from_pattern
+ *		(pat_rule, percent, result)
+ *
+ *	after pattern matched a target this routine is called to construct targets and dependencies
+ *	strings from this matched pattern rule and a string (percent) with substitutes % sign in pattern.
+ *
+ *	Return value:
+ *				none
+ *
+ *	Parameters:
+ *     		pat_rule 	matched pattern rule
+ *		percent		string containing matched % sign part.
+ *		result		holds the result of string construction.
+ *
+ */
+static void
+construct_string_from_pattern(Percent pat_rule, String percent, String result) {
+	for (int i = 0; i < pat_rule->patterns_total; i++) {
+		if (pat_rule->patterns[i]->dollar) {
+			expand_value(pat_rule->patterns[i],
+				     result,
+				     false);
+			
+		} else {
+			append_string(pat_rule->patterns[i]->string_mb,
+				      result,
+				      pat_rule->patterns[i]->hash.length);
+		}
+		
+		if (i < pat_rule->patterns_total - 1) {
+			append_string(percent->buffer.start,
+				      result,
+				      percent->text.p - percent->buffer.start);
+		}
+	}
+	
+	if ((result->buffer.start[0] == (int) period_char) &&
+	    (result->buffer.start[1] == (int) slash_char)) {
+		result->buffer.start += 2;
+	}
+}
+
+/*
+ *	dependency_exists(target, line)
+ *
+ *	Returns true if the target exists in the
+ *	dependency list of the line.
+ *
+ *	Return value:
+ *				True if target is on dependency list
+ *
+ *	Parameters:
+ *		target		Target we scan for
+ *		line		We get the dependency list from here
+ *
+ *	Global variables used:
+ */
+static Boolean
+dependency_exists(Name target, Property line)
+{
+	Dependency	dp;
+
+	if (line == NULL) {
+		return false;
+	}
+	for (dp = line->body.line.dependencies; dp != NULL; dp = dp->next) {
+		if (dp->name == target) {
+			return true;
+		}
+	}
+	return false;
+}
+
+void
+add_target_to_chain(Name target, Chain * query)
+{
+	if (target->is_member && (get_prop(target->prop, member_prop) != NULL)) {
+		target = get_prop(target->prop, member_prop)->body.member.member;
+	}
+	Chain	*query_tail;
+	for (query_tail = query; *query_tail != NULL; query_tail = &(*query_tail)->next) {
+		if ((*query_tail)->name == target) {
+			return;
+		}
+	}
+	*query_tail = ALLOC(Chain);
+	(*query_tail)->name = target;
+	(*query_tail)->next = NULL;
+}
+
--- /dev/null	2015-05-20 11:04:08.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/common/macro.cc	2015-05-20 11:04:08.928483763 -0400
@@ -0,0 +1,214 @@
+/*
+ * 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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)macro.cc 1.28 06/12/12
+ */
+
+#pragma	ident	"@(#)macro.cc	1.28	06/12/12"
+
+/*
+ *	macro.cc
+ *
+ *	Handle expansion of make macros
+ */
+
+/*
+ * Included files
+ */
+#ifdef DISTRIBUTED
+#include <avo/strings.h>	/* AVO_STRDUP() */
+#include <dm/Avo_DoJobMsg.h>
+#endif
+#include <mk/defs.h>
+#include <mksh/macro.h>		/* getvar(), expand_value() */
+#include <mksh/misc.h>		/* getmem() */
+
+/*
+ * Defined macros
+ */
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+
+/*
+ * File table of contents
+ */
+
+void
+setvar_append(register Name name, register Name value)
+{
+	register Property	macro_apx = get_prop(name->prop, macro_append_prop);
+	register Property	macro = get_prop(name->prop, macro_prop);
+	int			length;
+	String_rec		destination;
+	wchar_t			buffer[STRING_BUFFER_LENGTH];
+	register Chain		chain;
+	Name			val = NULL;
+
+	if(macro_apx == NULL) {
+		macro_apx = append_prop(name, macro_append_prop);
+		if(macro != NULL) {
+			macro_apx->body.macro_appendix.value = macro->body.macro.value;
+		}
+	}
+
+	val = macro_apx->body.macro_appendix.value_to_append;
+
+	INIT_STRING_FROM_STACK(destination, buffer);
+	buffer[0] = 0;
+	if (val != NULL) {
+		APPEND_NAME(val,
+			      &destination,
+			      (int) val->hash.length);
+		if (value != NULL) {
+			MBTOWC(wcs_buffer, " ");
+			append_char(wcs_buffer[0], &destination);
+		}
+	}
+	if (value != NULL) {
+		APPEND_NAME(value,
+			      &destination,
+			      (int) value->hash.length);
+	}
+	value = GETNAME(destination.buffer.start, FIND_LENGTH);
+	if (destination.free_after_use) {
+		retmem(destination.buffer.start);
+	}
+	macro_apx->body.macro_appendix.value_to_append = value;
+
+	SETVAR(name, empty_name, true);
+}
+
+/*
+ *	setvar_envvar()
+ *
+ *	This function scans the list of environment variables that have
+ *	dynamic values and sets them.
+ *
+ *	Parameters:
+ *
+ *	Global variables used:
+ *		envvar		A list of environment vars with $ in value
+ */
+void
+#ifdef DISTRIBUTED
+setvar_envvar(Avo_DoJobMsg *dmake_job_msg)
+#else
+setvar_envvar(void)
+#endif
+{
+	wchar_t			buffer[STRING_BUFFER_LENGTH];
+	int			length;
+#ifdef DISTRIBUTED
+	Property		macro;
+#endif
+	register	char	*mbs, *tmp_mbs_buffer = NULL;
+	register	char	*env, *tmp_mbs_buffer2 = NULL;
+	Envvar			p;
+	String_rec		value;
+
+	for (p = envvar; p != NULL; p = p->next) {
+		if (p->already_put
+#ifdef DISTRIBUTED
+		    && !dmake_job_msg
+#endif
+		    ) {
+			continue;
+		}
+		INIT_STRING_FROM_STACK(value, buffer);		
+		expand_value(p->value, &value, false);
+		if ((length = wslen(value.buffer.start)) >= MAXPATHLEN) {
+			mbs = tmp_mbs_buffer = getmem((length + 1) * MB_LEN_MAX);
+			(void) wcstombs(mbs,
+			                value.buffer.start,
+			                (length + 1) * MB_LEN_MAX);
+		} else {
+			mbs = mbs_buffer;
+			WCSTOMBS(mbs, value.buffer.start);
+		}
+		length = 2 + strlen(p->name->string_mb) + strlen(mbs);
+		if (!p->already_put || length > (MAXPATHLEN * MB_LEN_MAX)) {
+			env = tmp_mbs_buffer2 = getmem(length);
+		} else {
+			env = mbs_buffer2;
+		}
+		(void) sprintf(env,
+			       "%s=%s",
+			       p->name->string_mb,
+			       mbs);
+		if (!p->already_put) {
+			(void) putenv(env);
+			p->already_put = true;
+			if (p->env_string) {
+				retmem_mb(p->env_string);
+			}
+			p->env_string = env;
+			tmp_mbs_buffer2 = NULL; // We should not return this memory now
+		}
+#ifdef DISTRIBUTED
+		if (dmake_job_msg) {
+			dmake_job_msg->appendVar(env);
+		}
+#endif
+		if (tmp_mbs_buffer2) {
+			retmem_mb(tmp_mbs_buffer2);
+			tmp_mbs_buffer2 = NULL;
+		}
+		if (tmp_mbs_buffer) {
+			retmem_mb(tmp_mbs_buffer);
+			tmp_mbs_buffer = NULL;
+		}
+	}
+#ifdef DISTRIBUTED
+	/* Append SUNPRO_DEPENDENCIES to the dmake_job_msg. */
+	if (keep_state && dmake_job_msg) {
+		macro = get_prop(sunpro_dependencies->prop, macro_prop);
+		length = 2 +
+		         strlen(sunpro_dependencies->string_mb) +
+		         strlen(macro->body.macro.value->string_mb);
+		if (length > (MAXPATHLEN * MB_LEN_MAX)) {
+			env = tmp_mbs_buffer2 = getmem(length);
+		} else {
+			env = mbs_buffer2;
+		}
+		(void) sprintf(env,
+			       "%s=%s",
+			       sunpro_dependencies->string_mb,
+			       macro->body.macro.value->string_mb);
+		dmake_job_msg->appendVar(env);
+		if (tmp_mbs_buffer2) {
+			retmem_mb(tmp_mbs_buffer2);
+			tmp_mbs_buffer2 = NULL;
+		}
+	}
+#endif
+}
+
+
--- /dev/null	2015-05-20 11:04:09.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/common/main.cc	2015-05-20 11:04:09.132806011 -0400
@@ -0,0 +1,3787 @@
+/*
+ * 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.
+ */
+/*
+ * @(#)main.cc 1.158 06/12/12
+ */
+
+#pragma	ident	"@(#)main.cc	1.158	06/12/12"
+
+/*
+ *	main.cc
+ *
+ *	make program main routine plus some helper routines
+ */
+ 
+/*
+ * Included files
+ */
+#if defined(TEAMWARE_MAKE_CMN)
+#       include <avo/intl.h>
+#       include <avo/libcli.h>          /* libcli_init() */
+#	include <avo/cli_license.h>	/* avo_cli_get_license() */
+#	include <avo/find_dir.h>	/* avo_find_run_dir() */
+#	include <avo/version_string.h>
+#	include <avo/util.h>		/* avo_init() */
+#ifdef USE_DMS_CCR
+#	include <avo/usage_tracking.h>
+#else
+#	include <avo/cleanup.h>
+#endif
+#endif
+
+#if defined(TEAMWARE_MAKE_CMN)
+/* This is for dmake only (not for Solaris make).
+ * Include code to check updates (dmake patches)
+ */
+#ifdef _CHECK_UPDATE_H
+#include <libAU.h>
+#endif
+#endif
+
+#include <bsd/bsd.h>		/* bsd_signal() */
+
+#ifdef DISTRIBUTED
+#	include <dm/Avo_AcknowledgeMsg.h>
+#	include <rw/xdrstrea.h>
+#	include <dmrc/dmrc.h> /* dmakerc file processing */
+#endif
+
+#include <locale.h>		/* setlocale() */
+#include <mk/copyright.h>
+#include <mk/defs.h>
+#include <mksdmsi18n/mksdmsi18n.h>	/* libmksdmsi18n_init() */
+#include <mksh/macro.h>		/* getvar() */
+#include <mksh/misc.h>		/* getmem(), setup_char_semantics() */
+
+#if defined(TEAMWARE_MAKE_CMN)
+#ifdef USE_DMS_CCR
+#	include <pubdmsi18n/pubdmsi18n.h>	/* libpubdmsi18n_init() */
+#endif
+#endif
+
+#include <pwd.h>		/* getpwnam() */
+#include <setjmp.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <sys/errno.h>		/* ENOENT */
+#include <sys/stat.h>		/* fstat() */
+#include <fcntl.h>		/* open() */
+
+#ifdef SUN5_0
+#	include <sys/systeminfo.h>	/* sysinfo() */
+#endif
+
+#include <sys/types.h>		/* stat() */
+#include <sys/wait.h>		/* wait() */
+#include <unistd.h>		/* execv(), unlink(), access() */
+#include <vroot/report.h>	/* report_dependency(), get_report_file() */
+
+// From read2.cc
+extern	Name		normalize_name(register wchar_t *name_string, register int length);
+
+// From parallel.cc
+#if defined(TEAMWARE_MAKE_CMN)
+#define MAXJOBS_ADJUST_RFE4694000
+
+#ifdef MAXJOBS_ADJUST_RFE4694000
+extern void job_adjust_fini();
+#endif /* MAXJOBS_ADJUST_RFE4694000 */
+#endif /* TEAMWARE_MAKE_CMN */
+
+#if defined(linux)
+#include <ctype.h>
+#endif
+
+/*
+ * Defined macros
+ */
+#define	LD_SUPPORT_ENV_VAR	NOCATGETS("SGS_SUPPORT")
+#define	LD_SUPPORT_MAKE_LIB	NOCATGETS("libmakestate.so.1")
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+static	char		*argv_zero_string;
+static	Boolean		build_failed_ever_seen;
+static	Boolean		continue_after_error_ever_seen;	/* `-k' */
+static	Boolean		dmake_group_specified;		/* `-g' */
+static	Boolean		dmake_max_jobs_specified;	/* `-j' */
+static	Boolean		dmake_mode_specified;		/* `-m' */
+static	Boolean		dmake_add_mode_specified;	/* `-x' */
+static	Boolean		dmake_output_mode_specified;	/* `-x DMAKE_OUTPUT_MODE=' */
+static	Boolean		dmake_compat_mode_specified;	/* `-x SUN_MAKE_COMPAT_MODE=' */
+static	Boolean		dmake_odir_specified;		/* `-o' */
+static	Boolean		dmake_rcfile_specified;		/* `-c' */
+static	Boolean		env_wins;			/* `-e' */
+static	Boolean		ignore_default_mk;		/* `-r' */
+static	Boolean		list_all_targets;		/* `-T' */
+static	int		mf_argc;
+static	char		**mf_argv;
+static	Dependency_rec  not_auto_depen_struct;
+static	Dependency 	not_auto_depen = &not_auto_depen_struct;
+static	Boolean		pmake_cap_r_specified;		/* `-R' */
+static	Boolean		pmake_machinesfile_specified;	/* `-M' */
+static	Boolean		stop_after_error_ever_seen;	/* `-S' */
+static	Boolean		trace_status;			/* `-p' */
+
+#ifdef DMAKE_STATISTICS
+static	Boolean		getname_stat = false;
+#endif
+
+#if defined(TEAMWARE_MAKE_CMN)
+	static	time_t		start_time;
+	static	int		g_argc;
+	static	char		**g_argv;
+#ifdef USE_DMS_CCR
+	static  Avo_usage_tracking *usageTracking = NULL;
+#else
+	static  Avo_cleanup	*cleanup = NULL;
+#endif
+#endif
+
+/*
+ * File table of contents
+ */
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+	extern "C" void		cleanup_after_exit(void);
+#else
+	extern	void		cleanup_after_exit(int, ...);
+#endif
+
+#ifdef TEAMWARE_MAKE_CMN
+extern "C" {
+	extern	void		dmake_exit_callback(void);
+	extern	void		dmake_message_callback(char *);
+}
+#endif
+
+extern	Name		normalize_name(register wchar_t *name_string, register int length);
+
+extern	int		main(int, char * []);
+
+static	void		append_makeflags_string(Name, String);
+static	void		doalarm(int);
+static	void		enter_argv_values(int , char **, ASCII_Dyn_Array *);
+static	void		make_targets(int, char **, Boolean);
+static	int		parse_command_option(char);
+static	void		read_command_options(int, char **);
+static	void		read_environment(Boolean);
+static	void		read_files_and_state(int, char **);
+static	Boolean		read_makefile(Name, Boolean, Boolean, Boolean);
+static	void		report_recursion(Name);
+static	void		set_sgs_support(void);
+static	void		setup_for_projectdir(void);
+static	void		setup_makeflags_argv(void);
+static	void		report_dir_enter_leave(Boolean entering);
+
+extern void expand_value(Name, register String , Boolean);
+
+#ifdef DISTRIBUTED
+	extern	int		dmake_ofd;
+	extern	FILE*		dmake_ofp;
+	extern	int		rxmPid;
+	extern	XDR 		xdrs_out;
+#endif
+#ifdef TEAMWARE_MAKE_CMN
+	extern	char		verstring[];
+#endif
+
+jmp_buf jmpbuffer;
+#if !defined(linux)
+nl_catd catd;
+#endif
+
+/*
+ *	main(argc, argv)
+ *
+ *	Parameters:
+ *		argc			You know what this is
+ *		argv			You know what this is
+ *
+ *	Static variables used:
+ *		list_all_targets	make -T seen
+ *		trace_status		make -p seen
+ *
+ *	Global variables used:
+ *		debug_level		Should we trace make actions?
+ *		keep_state		Set if .KEEP_STATE seen
+ *		makeflags		The Name "MAKEFLAGS", used to get macro
+ *		remote_command_name	Name of remote invocation cmd ("on")
+ *		running_list		List of parallel running processes
+ *		stdout_stderr_same	true if stdout and stderr are the same
+ *		auto_dependencies	The Name "SUNPRO_DEPENDENCIES"
+ *		temp_file_directory	Set to the dir where we create tmp file
+ *		trace_reader		Set to reflect tracing status
+ *		working_on_targets	Set when building user targets
+ */
+int
+main(int argc, char *argv[])
+{
+	/*
+	 * cp is a -> to the value of the MAKEFLAGS env var,
+	 * which has to be regular chars.
+	 */
+	register char		*cp;
+	char 			make_state_dir[MAXPATHLEN];
+	Boolean			parallel_flag = false;
+	char			*prognameptr;
+	char 			*slash_ptr;
+	mode_t			um;
+	int			i;
+#ifdef TEAMWARE_MAKE_CMN
+	struct itimerval	value;
+	char			def_dmakerc_path[MAXPATHLEN];
+	Name			dmake_name, dmake_name2;
+	Name			dmake_value, dmake_value2;
+	Property		prop, prop2;
+	struct stat		statbuf;
+	int			statval;
+#endif
+
+#ifndef PARALLEL
+	struct stat		out_stat, err_stat;
+#endif
+	hostid = gethostid();
+#ifdef TEAMWARE_MAKE_CMN
+	avo_get_user(NULL, NULL); // Initialize user name
+#endif
+	bsd_signals();
+
+	(void) setlocale(LC_ALL, "");
+
+#if defined (HP_UX) || defined(linux)
+       /* HP-UX users typically will not have NLSPATH set, and this binary
+        * requires that it be set.  On HP-UX 9.0x, /usr/lib/nls/%L/%N.cat is
+        * the path to set it to.
+        */
+
+       if (getenv(NOCATGETS("NLSPATH")) == NULL) {
+         putenv(NOCATGETS("NLSPATH=/usr/lib/nls/%L/%N.cat"));
+	}
+#endif
+
+#ifdef DMAKE_STATISTICS
+	if (getenv(NOCATGETS("DMAKE_STATISTICS"))) {
+		getname_stat = true;
+	}
+#endif
+
+
+	/*
+	 * avo_init() sets the umask to 0.  Save it here and restore
+	 * it after the avo_init() call.
+	 */
+#if defined(TEAMWARE_MAKE_CMN) || defined(MAKETOOL)
+	um = umask(0);
+	avo_init(argv[0]);
+	umask(um);
+
+#ifdef USE_DMS_CCR
+	usageTracking = new Avo_usage_tracking(NOCATGETS("dmake"), argc, argv);
+#else
+	cleanup = new Avo_cleanup(NOCATGETS("dmake"), argc, argv);
+#endif
+#endif
+
+#if defined(TEAMWARE_MAKE_CMN)
+	catd = catopen(AVO_DOMAIN_DMAKE, NL_CAT_LOCALE);
+	libcli_init();
+
+#ifdef _CHECK_UPDATE_H
+	/* This is for dmake only (not for Solaris make).
+	 * Check (in background) if there is an update (dmake patch)
+	 * and inform user
+	 */
+	{
+		Avo_err		*err;
+		char		*dir;
+		err = avo_find_run_dir(&dir);
+		if (AVO_OK == err) {
+			AU_check_update_service(NOCATGETS("Dmake"), dir);
+		}
+	}
+#endif /* _CHECK_UPDATE_H */
+#endif
+
+// ---> fprintf(stderr, catgets(catd, 15, 666, "--- SUN make ---\n"));
+
+
+#if defined(TEAMWARE_MAKE_CMN) || defined(MAKETOOL)
+/*
+ * I put libmksdmsi18n_init() under #ifdef because it requires avo_i18n_init()
+ * from avo_util library. 
+ */
+	libmksdmsi18n_init();
+#ifdef USE_DMS_CCR
+	libpubdmsi18n_init();
+#endif
+#endif
+
+
+#ifndef TEAMWARE_MAKE_CMN
+	textdomain(NOCATGETS("SUNW_SPRO_MAKE"));
+#endif /* TEAMWARE_MAKE_CMN */
+
+#ifdef TEAMWARE_MAKE_CMN
+	g_argc = argc;
+	g_argv = (char **) malloc((g_argc + 1) * sizeof(char *));
+	for (i = 0; i < argc; i++) {
+		g_argv[i] = argv[i];
+	}
+	g_argv[i] = NULL;
+#endif /* TEAMWARE_MAKE_CMN */
+
+	/*
+	 * Set argv_zero_string to some form of argv[0] for
+	 * recursive MAKE builds.
+	 */
+
+	if (*argv[0] == (int) slash_char) {
+		/* argv[0] starts with a slash */
+		argv_zero_string = strdup(argv[0]);
+	} else if (strchr(argv[0], (int) slash_char) == NULL) {
+		/* argv[0] contains no slashes */
+		argv_zero_string = strdup(argv[0]);
+	} else {
+		/*
+		 * argv[0] contains at least one slash,
+		 * but doesn't start with a slash
+		 */
+		char	*tmp_current_path;
+		char	*tmp_string;
+
+		tmp_current_path = get_current_path();
+		tmp_string = getmem(strlen(tmp_current_path) + 1 +
+		                    strlen(argv[0]) + 1);
+		(void) sprintf(tmp_string,
+		               "%s/%s",
+		               tmp_current_path,
+		               argv[0]);
+		argv_zero_string = strdup(tmp_string);
+		retmem_mb(tmp_string);
+	}
+
+	/* 
+	 * The following flags are reset if we don't have the 
+	 * (.nse_depinfo or .make.state) files locked and only set 
+	 * AFTER the file has been locked. This ensures that if the user
+	 * interrupts the program while file_lock() is waiting to lock
+	 * the file, the interrupt handler doesn't remove a lock 
+	 * that doesn't belong to us.
+	 */
+	make_state_lockfile = NULL;
+	make_state_locked = false;
+
+#ifdef NSE
+	nse_depinfo_lockfile[0] = '\0';
+	nse_depinfo_locked = false; 
+#endif
+
+	/*
+	 * look for last slash char in the path to look at the binary 
+	 * name. This is to resolve the hard link and invoke make
+	 * in svr4 mode.
+	 */
+
+	/* Sun OS make standart */
+	svr4 = false;  
+	posix = false;
+	if(!strcmp(argv_zero_string, NOCATGETS("/usr/xpg4/bin/make"))) {
+		svr4 = false;
+		posix = true;
+	} else {
+		prognameptr = strrchr(argv[0], '/');
+		if(prognameptr) {
+			prognameptr++;
+		} else {
+			prognameptr = argv[0];
+		}
+		if(!strcmp(prognameptr, NOCATGETS("svr4.make"))) {
+			svr4 = true;
+			posix = false;
+		}
+	}
+#if !defined(HP_UX) && !defined(linux)
+	if (getenv(USE_SVR4_MAKE) || getenv(NOCATGETS("USE_SVID"))){
+	   svr4 = true;
+	   posix = false;
+	}
+#endif
+
+	/*
+	 * Find the dmake_compat_mode: posix, sun, svr4, or gnu_style, .
+	 */
+	char * dmake_compat_mode_var = getenv(NOCATGETS("SUN_MAKE_COMPAT_MODE"));
+	if (dmake_compat_mode_var != NULL) {
+		if (0 == strcasecmp(dmake_compat_mode_var, NOCATGETS("GNU"))) {
+			gnu_style = true;
+		}
+		//svr4 = false;
+		//posix = false;
+	}
+
+	/*
+	 * Temporary directory set up.
+	 */
+	char * tmpdir_var = getenv(NOCATGETS("TMPDIR"));
+	if (tmpdir_var != NULL && *tmpdir_var == '/' && strlen(tmpdir_var) < MAXPATHLEN) {
+		strcpy(mbs_buffer, tmpdir_var);
+		for (tmpdir_var = mbs_buffer+strlen(mbs_buffer);
+			*(--tmpdir_var) == '/' && tmpdir_var > mbs_buffer;
+			*tmpdir_var = '\0');
+		if (strlen(mbs_buffer) + 32 < MAXPATHLEN) { /* 32 = strlen("/dmake.stdout.%d.%d.XXXXXX") */
+			sprintf(mbs_buffer2, NOCATGETS("%s/dmake.tst.%d.XXXXXX"),
+				mbs_buffer, getpid());
+			int fd = mkstemp(mbs_buffer2);
+			if (fd >= 0) {
+				close(fd);
+				unlink(mbs_buffer2);
+				tmpdir = strdup(mbs_buffer);
+			}
+		}
+	}
+
+#ifndef PARALLEL
+	/* find out if stdout and stderr point to the same place */
+	if (fstat(1, &out_stat) < 0) {
+		fatal(catgets(catd, 1, 165, "fstat of standard out failed: %s"), errmsg(errno));
+	}
+	if (fstat(2, &err_stat) < 0) {
+		fatal(catgets(catd, 1, 166, "fstat of standard error failed: %s"), errmsg(errno));
+	}
+	if ((out_stat.st_dev == err_stat.st_dev) &&
+	    (out_stat.st_ino == err_stat.st_ino)) {
+		stdout_stderr_same = true;
+	} else {
+		stdout_stderr_same = false;
+	}
+#else
+	stdout_stderr_same = false;
+#endif
+	/* Make the vroot package scan the path using shell semantics */
+	set_path_style(0);
+
+	setup_char_semantics();
+
+	setup_for_projectdir();
+
+	/*
+	 * If running with .KEEP_STATE, curdir will be set with
+	 * the connected directory.
+	 */
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+	(void) atexit(cleanup_after_exit);
+#else
+	(void) on_exit(cleanup_after_exit, (char *) NULL);
+#endif
+
+	load_cached_names();
+
+/*
+ *	Set command line flags
+ */
+	setup_makeflags_argv();
+	read_command_options(mf_argc, mf_argv);
+	read_command_options(argc, argv);
+	if (debug_level > 0) {
+		cp = getenv(makeflags->string_mb);
+		(void) printf(catgets(catd, 1, 167, "MAKEFLAGS value: %s\n"), cp == NULL ? "" : cp);
+	}
+
+	setup_interrupt(handle_interrupt);
+
+	read_files_and_state(argc, argv);
+
+#ifdef TEAMWARE_MAKE_CMN
+	/*
+	 * Find the dmake_output_mode: TXT1, TXT2 or HTML1.
+	 */
+	MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_OUTPUT_MODE"));
+	dmake_name2 = GETNAME(wcs_buffer, FIND_LENGTH);
+	prop2 = get_prop(dmake_name2->prop, macro_prop);
+	if (prop2 == NULL) {
+		/* DMAKE_OUTPUT_MODE not defined, default to TXT1 mode */
+		output_mode = txt1_mode;
+	} else {
+		dmake_value2 = prop2->body.macro.value;
+		if ((dmake_value2 == NULL) ||
+		    (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("TXT1")))) {
+			output_mode = txt1_mode;
+		} else if (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("TXT2"))) {
+			output_mode = txt2_mode;
+		} else if (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("HTML1"))) {
+			output_mode = html1_mode;
+		} else {
+			warning(catgets(catd, 1, 352, "Unsupported value `%s' for DMAKE_OUTPUT_MODE after -x flag (ignored)"),
+			      dmake_value2->string_mb);
+		}
+	}
+	/*
+	 * Find the dmake_mode: distributed, parallel, or serial.
+	 */
+    if ((!pmake_cap_r_specified) &&
+        (!pmake_machinesfile_specified)) {
+	MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MODE"));
+	dmake_name2 = GETNAME(wcs_buffer, FIND_LENGTH);
+	prop2 = get_prop(dmake_name2->prop, macro_prop);
+	if (prop2 == NULL) {
+		/* DMAKE_MODE not defined, default to distributed mode */
+		dmake_mode_type = distributed_mode;
+		no_parallel = false;
+	} else {
+		dmake_value2 = prop2->body.macro.value;
+		if ((dmake_value2 == NULL) ||
+		    (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("distributed")))) {
+			dmake_mode_type = distributed_mode;
+			no_parallel = false;
+		} else if (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("parallel"))) {
+			dmake_mode_type = parallel_mode;
+			no_parallel = false;
+#ifdef SGE_SUPPORT
+			grid = false;
+		} else if (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("grid"))) {
+			dmake_mode_type = parallel_mode;
+			no_parallel = false;
+			grid = true;
+#endif
+		} else if (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("serial"))) {
+			dmake_mode_type = serial_mode;
+			no_parallel = true;
+		} else {
+			fatal(catgets(catd, 1, 307, "Unknown dmake mode argument `%s' after -m flag"), dmake_value2->string_mb);
+		}
+	}
+
+	if ((!list_all_targets) &&
+	    (report_dependencies_level == 0)) {
+		/*
+		 * Check to see if either DMAKE_RCFILE or DMAKE_MODE is defined.
+		 * They could be defined in the env, in the makefile, or on the
+		 * command line.
+		 * If neither is defined, and $(HOME)/.dmakerc does not exists,
+		 * then print a message, and default to parallel mode.
+		 */
+#ifdef DISTRIBUTED
+		MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_RCFILE"));
+		dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
+		MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MODE"));
+		dmake_name2 = GETNAME(wcs_buffer, FIND_LENGTH);
+		if ((((prop = get_prop(dmake_name->prop, macro_prop)) == NULL) ||
+		     ((dmake_value = prop->body.macro.value) == NULL)) &&
+		    (((prop2 = get_prop(dmake_name2->prop, macro_prop)) == NULL) ||
+		     ((dmake_value2 = prop2->body.macro.value) == NULL))) {
+			Boolean empty_dmakerc = true;
+			char *homedir = getenv(NOCATGETS("HOME"));
+			if ((homedir != NULL) && (strlen(homedir) < (sizeof(def_dmakerc_path) - 16))) {
+				sprintf(def_dmakerc_path, NOCATGETS("%s/.dmakerc"), homedir);
+				if ((((statval = stat(def_dmakerc_path, &statbuf)) != 0) && (errno == ENOENT)) ||
+					((statval == 0) && (statbuf.st_size == 0))) {
+				} else {
+					Avo_dmakerc	*rcfile = new Avo_dmakerc();
+					Avo_err		*err = rcfile->read(def_dmakerc_path, NULL, TRUE);
+					if (err) {
+						fatal(err->str);
+					}
+					empty_dmakerc = rcfile->was_empty();
+					delete rcfile;
+				}
+			}
+			if (empty_dmakerc) {
+				if (getenv(NOCATGETS("DMAKE_DEF_PRINTED")) == NULL) {
+					putenv(NOCATGETS("DMAKE_DEF_PRINTED=TRUE"));
+					(void) fprintf(stdout, catgets(catd, 1, 302, "dmake: defaulting to parallel mode.\n"));
+					(void) fprintf(stdout, catgets(catd, 1, 303, "See the man page dmake(1) for more information on setting up the .dmakerc file.\n"));
+				}
+				dmake_mode_type = parallel_mode;
+				no_parallel = false;
+			}
+		}
+#else
+		if(dmake_mode_type == distributed_mode) {
+			(void) fprintf(stdout, NOCATGETS("dmake: Distributed mode not implemented.\n"));
+			(void) fprintf(stdout, NOCATGETS("       Defaulting to parallel mode.\n"));
+			dmake_mode_type = parallel_mode;
+			no_parallel = false;
+		}
+#endif	/* DISTRIBUTED */
+	}
+    }
+#endif
+
+#ifdef TEAMWARE_MAKE_CMN
+	parallel_flag = true;
+	/* XXX - This is a major hack for DMake/Licensing. */
+	if (getenv(NOCATGETS("DMAKE_CHILD")) == NULL) {
+		if (!avo_cli_search_license(argv[0], dmake_exit_callback, TRUE, dmake_message_callback)) {
+			/*
+			 * If the user can not get a TeamWare license,
+			 * default to serial mode.
+			 */
+			dmake_mode_type = serial_mode;
+			no_parallel = true;
+		} else {
+			putenv(NOCATGETS("DMAKE_CHILD=TRUE"));
+		}
+		start_time = time(NULL);
+		/*
+		 * XXX - Hack to disable SIGALRM's from licensing library's
+		 *       setitimer().
+		 */
+		value.it_interval.tv_sec = 0;
+		value.it_interval.tv_usec = 0;
+		value.it_value.tv_sec = 0;
+		value.it_value.tv_usec = 0;
+		(void) setitimer(ITIMER_REAL, &value, NULL);
+	}
+
+//
+// If dmake is running with -t option, set dmake_mode_type to serial.
+// This is done because doname() calls touch_command() that runs serially.
+// If we do not do that, maketool will have problems. 
+//
+	if(touch) {
+		dmake_mode_type = serial_mode;
+		no_parallel = true;
+	}
+#else
+	parallel_flag = false;
+#endif
+
+#if defined (TEAMWARE_MAKE_CMN) && defined(REDIRECT_ERR)
+	/*
+	 * Check whether stdout and stderr are physically same.
+	 * This is in order to decide whether we need to redirect
+	 * stderr separately from stdout.
+	 * This check is performed only if __DMAKE_SEPARATE_STDERR
+	 * is not set. This variable may be used in order to preserve
+	 * the 'old' behaviour.
+	 */
+	out_err_same = true;
+	char * dmake_sep_var = getenv(NOCATGETS("__DMAKE_SEPARATE_STDERR"));
+	if (dmake_sep_var == NULL || (0 != strcasecmp(dmake_sep_var, NOCATGETS("NO")))) {
+		struct stat stdout_stat;
+		struct stat stderr_stat;
+		if( (fstat(1, &stdout_stat) == 0)
+		 && (fstat(2, &stderr_stat) == 0) )
+		{
+			if( (stdout_stat.st_dev != stderr_stat.st_dev)
+			 || (stdout_stat.st_ino != stderr_stat.st_ino) )
+			{
+				out_err_same = false;
+			}
+		}
+	}
+#endif
+
+#ifdef DISTRIBUTED
+	/*
+	 * At this point, DMake should startup an rxm with any and all
+	 * DMake command line options. Rxm will, among other things,
+	 * read the rc file.
+	 */
+	if ((!list_all_targets) &&
+	    (report_dependencies_level == 0) &&
+	    (dmake_mode_type == distributed_mode)) {
+		startup_rxm();
+	}
+#endif
+		
+/*
+ *	Enable interrupt handler for alarms
+ */
+        (void) bsd_signal(SIGALRM, (SIG_PF)doalarm);
+
+/*
+ *	Check if make should report
+ */
+	if (getenv(sunpro_dependencies->string_mb) != NULL) {
+		FILE	*report_file;
+
+		report_dependency("");
+		report_file = get_report_file();
+		if ((report_file != NULL) && (report_file != (FILE*)-1)) {
+			(void) fprintf(report_file, "\n");
+		}
+	}
+
+/*
+ *	Make sure SUNPRO_DEPENDENCIES is exported (or not) properly
+ *      and NSE_DEP.
+ */
+	if (keep_state) {
+		maybe_append_prop(sunpro_dependencies, macro_prop)->
+		  body.macro.exported = true;
+#ifdef NSE
+		(void) setenv(NOCATGETS("NSE_DEP"), get_current_path());
+#endif
+	} else {
+		maybe_append_prop(sunpro_dependencies, macro_prop)->
+		  body.macro.exported = false;
+	}
+
+	working_on_targets = true;
+	if (trace_status) {
+		dump_make_state();
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+		fclose(stdout);
+		fclose(stderr);
+		exit_status = 0;
+#endif
+		exit(0);
+	}
+	if (list_all_targets) {
+		dump_target_list();
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+		fclose(stdout);
+		fclose(stderr);
+		exit_status = 0;
+#endif
+		exit(0);
+	}
+	trace_reader = false;
+
+ 	/*
+ 	 * Set temp_file_directory to the directory the .make.state
+ 	 * file is written to.
+ 	 */
+ 	if ((slash_ptr = strrchr(make_state->string_mb, (int) slash_char)) == NULL) {
+ 		temp_file_directory = strdup(get_current_path());
+ 	} else {
+ 		*slash_ptr = (int) nul_char;
+ 		(void) strcpy(make_state_dir, make_state->string_mb);
+ 		*slash_ptr = (int) slash_char;
+		   /* when there is only one slash and it's the first
+		   ** character, make_state_dir should point to '/'.
+		   */
+		if(make_state_dir[0] == '\0') {
+		   make_state_dir[0] = '/';
+		   make_state_dir[1] = '\0';
+		}
+ 		if (make_state_dir[0] == (int) slash_char) {
+ 			temp_file_directory = strdup(make_state_dir);
+ 		} else {
+ 			char	tmp_current_path2[MAXPATHLEN];
+ 
+ 			(void) sprintf(tmp_current_path2,
+ 			               "%s/%s",
+ 			               get_current_path(),
+ 			               make_state_dir);
+ 			temp_file_directory = strdup(tmp_current_path2);
+ 		}
+ 	}
+
+#ifdef DISTRIBUTED
+	building_serial = false;
+#endif
+
+	report_dir_enter_leave(true);
+
+	make_targets(argc, argv, parallel_flag);
+
+	report_dir_enter_leave(false);
+
+#ifdef NSE
+        exit(nse_exit_status());
+#else
+	if (build_failed_ever_seen) {
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+		if (posix) {
+			exit_status = 1;
+		}
+#endif
+		exit(1);
+	}
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+	exit_status = 0;
+#endif
+	exit(0);
+#endif
+	/* NOTREACHED */
+}
+
+/*
+ *	cleanup_after_exit()
+ *
+ *	Called from exit(), performs cleanup actions.
+ *
+ *	Parameters:
+ *		status		The argument exit() was called with
+ *		arg		Address of an argument vector to
+ *				cleanup_after_exit()
+ *
+ *	Global variables used:
+ *		command_changed	Set if we think .make.state should be rewritten
+ *		current_line	Is set we set commands_changed
+ *		do_not_exec_rule
+ *				True if -n flag on
+ *		done		The Name ".DONE", rule we run
+ *		keep_state	Set if .KEEP_STATE seen
+ *		parallel	True if building in parallel
+ *		quest		If -q is on we do not run .DONE
+ *		report_dependencies
+ *				True if -P flag on
+ *		running_list	List of parallel running processes
+ *		temp_file_name	The temp file is removed, if any
+ *		catd	the message catalog file
+ *		usage_tracking  Should have been constructed in main()
+ *			        should destroyed just before exiting
+ */
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+extern "C" void
+cleanup_after_exit(void)
+#else
+void cleanup_after_exit(int status, ...)
+#endif
+{
+	Running		rp;
+#ifdef NSE
+	char		push_cmd[NSE_TFS_PUSH_LEN + 3 +
+			         (MAXPATHLEN * MB_LEN_MAX) + 12];
+	char		*active;
+#endif
+
+extern long	getname_bytes_count;
+extern long	getname_names_count;
+extern long	getname_struct_count;
+extern long	freename_bytes_count;
+extern long	freename_names_count;
+extern long	freename_struct_count;
+extern long	other_alloc;
+
+extern long	env_alloc_num;
+extern long	env_alloc_bytes;
+
+
+#ifdef DMAKE_STATISTICS
+if(getname_stat) {
+	printf(NOCATGETS(">>> Getname statistics:\n"));
+	printf(NOCATGETS("  Allocated:\n"));
+	printf(NOCATGETS("        Names: %ld\n"), getname_names_count);
+	printf(NOCATGETS("      Strings: %ld Kb (%ld bytes)\n"), getname_bytes_count/1000, getname_bytes_count);
+	printf(NOCATGETS("      Structs: %ld Kb (%ld bytes)\n"), getname_struct_count/1000, getname_struct_count);
+	printf(NOCATGETS("  Total bytes: %ld Kb (%ld bytes)\n"), getname_struct_count/1000 + getname_bytes_count/1000, getname_struct_count + getname_bytes_count);
+
+	printf(NOCATGETS("\n  Unallocated: %ld\n"), freename_names_count);
+	printf(NOCATGETS("        Names: %ld\n"), freename_names_count);
+	printf(NOCATGETS("      Strings: %ld Kb (%ld bytes)\n"), freename_bytes_count/1000, freename_bytes_count);
+	printf(NOCATGETS("      Structs: %ld Kb (%ld bytes)\n"), freename_struct_count/1000, freename_struct_count);
+	printf(NOCATGETS("  Total bytes: %ld Kb (%ld bytes)\n"), freename_struct_count/1000 + freename_bytes_count/1000, freename_struct_count + freename_bytes_count);
+
+	printf(NOCATGETS("\n  Total used: %ld Kb (%ld bytes)\n"), (getname_struct_count/1000 + getname_bytes_count/1000) - (freename_struct_count/1000 + freename_bytes_count/1000), (getname_struct_count + getname_bytes_count) - (freename_struct_count + freename_bytes_count));
+
+	printf(NOCATGETS("\n>>> Other:\n"));
+	printf(
+		NOCATGETS("       Env (%ld): %ld Kb (%ld bytes)\n"),
+		env_alloc_num,
+		env_alloc_bytes/1000,
+		env_alloc_bytes
+	);
+
+}
+#endif
+
+/*
+#ifdef DISTRIBUTED
+    if (get_parent() == TRUE) {
+#endif
+ */
+
+	parallel = false;
+#ifdef SUN5_0
+	/* If we used the SVR4_MAKE, don't build .DONE or .FAILED */
+	if (!getenv(USE_SVR4_MAKE)){
+#endif
+	    /* Build the target .DONE or .FAILED if we caught an error */
+	    if (!quest && !list_all_targets) {
+		Name		failed_name;
+
+		MBSTOWCS(wcs_buffer, NOCATGETS(".FAILED"));
+		failed_name = GETNAME(wcs_buffer, FIND_LENGTH);
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+		if ((exit_status != 0) && (failed_name->prop != NULL)) {
+#else
+		if ((status != 0) && (failed_name->prop != NULL)) {
+#endif
+#ifdef TEAMWARE_MAKE_CMN
+			/*
+			 * [tolik] switch DMake to serial mode
+			 */
+			dmake_mode_type = serial_mode;
+			no_parallel = true;
+#endif
+			(void) doname(failed_name, false, true);
+		} else {
+		    if (!trace_status) {
+#ifdef TEAMWARE_MAKE_CMN
+			/*
+			 * Switch DMake to serial mode
+			 */
+			dmake_mode_type = serial_mode;
+			no_parallel = true;
+#endif
+			(void) doname(done, false, true);
+		    }
+		}
+	    }
+#ifdef SUN5_0
+	}
+#endif
+	/*
+	 * Remove the temp file utilities report dependencies thru if it
+	 * is still around
+	 */
+	if (temp_file_name != NULL) {
+		(void) unlink(temp_file_name->string_mb);
+	}
+	/*
+	 * Do not save the current command in .make.state if make
+	 * was interrupted.
+	 */
+	if (current_line != NULL) {
+		command_changed = true;
+		current_line->body.line.command_used = NULL;
+	}
+	/*
+	 * For each parallel build process running, remove the temp files
+	 * and zap the command line so it won't be put in .make.state
+	 */
+	for (rp = running_list; rp != NULL; rp = rp->next) {
+		if (rp->temp_file != NULL) {
+			(void) unlink(rp->temp_file->string_mb);
+		}
+		if (rp->stdout_file != NULL) {
+			(void) unlink(rp->stdout_file);
+			retmem_mb(rp->stdout_file);
+			rp->stdout_file = NULL;
+		}
+		if (rp->stderr_file != NULL) {
+			(void) unlink(rp->stderr_file);
+			retmem_mb(rp->stderr_file);
+			rp->stderr_file = NULL;
+		}
+		command_changed = true;
+/*
+		line = get_prop(rp->target->prop, line_prop);
+		if (line != NULL) {
+			line->body.line.command_used = NULL;
+		}
+ */
+	}
+	/* Remove the statefile lock file if the file has been locked */
+	if ((make_state_lockfile != NULL) && (make_state_locked)) {
+		(void) unlink(make_state_lockfile);
+		make_state_lockfile = NULL;
+		make_state_locked = false;
+	}
+	/* Write .make.state */
+	write_state_file(1, (Boolean) 1);
+
+#ifdef TEAMWARE_MAKE_CMN
+	// Deleting the usage tracking object sends the usage mail 
+#ifdef USE_DMS_CCR
+	//usageTracking->setExitStatus(exit_status, NULL);
+	//delete usageTracking;
+#else
+	cleanup->set_exit_status(exit_status);
+	delete cleanup;
+#endif
+#endif
+
+#ifdef NSE
+        /* If running inside an activated environment, push the */
+	/* .nse_depinfo file (if written) */
+	active = getenv(NSE_VARIANT_ENV);
+	if (keep_state &&
+	    (active != NULL) &&
+	    !IS_EQUAL(active, NSE_RT_SOURCE_NAME) &&
+	    !do_not_exec_rule &&
+	    (report_dependencies_level == 0)) {
+		(void) sprintf(push_cmd,
+			       "%s %s/%s",
+			       NSE_TFS_PUSH,
+			       get_current_path(),
+			       NSE_DEPINFO);
+		(void) system(push_cmd);
+	}
+#endif
+
+/*
+#ifdef DISTRIBUTED
+    }
+#endif
+ */
+
+#if defined (TEAMWARE_MAKE_CMN) && defined (MAXJOBS_ADJUST_RFE4694000)
+	job_adjust_fini();
+#endif
+
+#ifdef TEAMWARE_MAKE_CMN
+	catclose(catd);
+#endif
+#ifdef DISTRIBUTED
+	if (rxmPid > 0) {
+		// Tell rxm to exit by sending it an Avo_AcknowledgeMsg
+		Avo_AcknowledgeMsg acknowledgeMsg;
+		RWCollectable *msg = (RWCollectable *)&acknowledgeMsg;
+
+		int xdrResult = xdr(&xdrs_out, msg);
+
+		if (xdrResult) {
+			fflush(dmake_ofp);
+		} else {
+/*
+			fatal(catgets(catd, 1, 266, "couldn't tell rxm to exit"));
+ */
+			kill(rxmPid, SIGTERM);
+		}
+
+		waitpid(rxmPid, NULL, 0);
+		rxmPid = 0;
+	}
+#endif
+}
+
+/*
+ *	handle_interrupt()
+ *
+ *	This is where C-C traps are caught.
+ *
+ *	Parameters:
+ *
+ *	Global variables used (except DMake 1.0):
+ *		current_target		Sometimes the current target is removed
+ *		do_not_exec_rule	But not if -n is on
+ *		quest			or -q
+ *		running_list		List of parallel running processes
+ *		touch			Current target is not removed if -t on
+ */
+void
+handle_interrupt(int)
+{
+	Property		member;
+	Running			rp;
+
+	(void) fflush(stdout);
+#ifdef DISTRIBUTED
+	if (rxmPid > 0) {
+		// Tell rxm to exit by sending it an Avo_AcknowledgeMsg
+		Avo_AcknowledgeMsg acknowledgeMsg;
+		RWCollectable *msg = (RWCollectable *)&acknowledgeMsg;
+
+		int xdrResult = xdr(&xdrs_out, msg);
+
+		if (xdrResult) {
+			fflush(dmake_ofp);
+		} else {
+			kill(rxmPid, SIGTERM);
+			rxmPid = 0;
+		}
+	}
+#endif
+	if (childPid > 0) {
+		kill(childPid, SIGTERM);
+		childPid = -1;
+	}
+	for (rp = running_list; rp != NULL; rp = rp->next) {
+		if (rp->state != build_running) {
+			continue;
+		}
+		if (rp->pid > 0) {
+			kill(rp->pid, SIGTERM);
+			rp->pid = -1;
+		}
+	}
+	if (getpid() == getpgrp()) {
+		bsd_signal(SIGTERM, SIG_IGN);
+		kill (-getpid(), SIGTERM);
+	}
+#ifdef TEAMWARE_MAKE_CMN
+	/* Clean up all parallel/distributed children already finished */
+        finish_children(false);
+#endif
+
+	/* Make sure the processes running under us terminate first */
+
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+	while (wait((int *) NULL) != -1);
+#else
+	while (wait((union wait*) NULL) != -1);
+#endif
+	/* Delete the current targets unless they are precious */
+	if ((current_target != NULL) &&
+	    current_target->is_member &&
+	    ((member = get_prop(current_target->prop, member_prop)) != NULL)) {
+		current_target = member->body.member.library;
+	}
+	if (!do_not_exec_rule &&
+	    !touch &&
+	    !quest &&
+	    (current_target != NULL) &&
+	    !(current_target->stat.is_precious || all_precious)) {
+
+/* BID_1030811 */
+/* azv 16 Oct 95 */
+		current_target->stat.time = file_no_time; 
+
+		if (exists(current_target) != file_doesnt_exist) {
+			(void) fprintf(stderr,
+				       "\n*** %s ",
+				       current_target->string_mb);
+			if (current_target->stat.is_dir) {
+				(void) fprintf(stderr,
+					       catgets(catd, 1, 168, "not removed.\n"),
+					       current_target->string_mb);
+			} else if (unlink(current_target->string_mb) == 0) {
+				(void) fprintf(stderr,
+					       catgets(catd, 1, 169, "removed.\n"),
+					       current_target->string_mb);
+			} else {
+				(void) fprintf(stderr,
+					       catgets(catd, 1, 170, "could not be removed: %s.\n"),
+					       current_target->string_mb,
+					       errmsg(errno));
+			}
+		}
+	}
+	for (rp = running_list; rp != NULL; rp = rp->next) {
+		if (rp->state != build_running) {
+			continue;
+		}
+		if (rp->target->is_member &&
+		    ((member = get_prop(rp->target->prop, member_prop)) !=
+		     NULL)) {
+			rp->target = member->body.member.library;
+		}
+		if (!do_not_exec_rule &&
+		    !touch &&
+		    !quest &&
+		    !(rp->target->stat.is_precious || all_precious)) {
+
+			rp->target->stat.time = file_no_time; 
+			if (exists(rp->target) != file_doesnt_exist) {
+				(void) fprintf(stderr,
+					       "\n*** %s ",
+					       rp->target->string_mb);
+				if (rp->target->stat.is_dir) {
+					(void) fprintf(stderr,
+						       catgets(catd, 1, 171, "not removed.\n"),
+						       rp->target->string_mb);
+				} else if (unlink(rp->target->string_mb) == 0) {
+					(void) fprintf(stderr,
+						       catgets(catd, 1, 172, "removed.\n"),
+						       rp->target->string_mb);
+				} else {
+					(void) fprintf(stderr,
+						       catgets(catd, 1, 173, "could not be removed: %s.\n"),
+						       rp->target->string_mb,
+						       errmsg(errno));
+				}
+			}
+		}
+	}
+
+#ifdef SGE_SUPPORT
+	/* Remove SGE script file */
+	if (grid) {
+		unlink(script_file);
+	}
+#endif
+
+	/* Have we locked .make.state or .nse_depinfo? */
+	if ((make_state_lockfile != NULL) && (make_state_locked)) {
+		unlink(make_state_lockfile);
+		make_state_lockfile = NULL;
+		make_state_locked = false;
+	}
+#ifdef NSE
+	if ((nse_depinfo_lockfile[0] != '\0') && (nse_depinfo_locked)) {
+		unlink(nse_depinfo_lockfile);
+		nse_depinfo_lockfile[0] = '\0';
+		nse_depinfo_locked = false;
+	}
+#endif
+	/*
+	 * Re-read .make.state file (it might be changed by recursive make)
+	 */
+	check_state(NULL);
+
+	report_dir_enter_leave(false);
+
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+	exit_status = 2;
+#endif
+	exit(2);
+}
+
+/*
+ *	doalarm(sig, ...)
+ *
+ *	Handle the alarm interrupt but do nothing.  Side effect is to
+ *	cause return from wait3.
+ *
+ *	Parameters:
+ *		sig
+ *
+ *	Global variables used:
+ */
+/*ARGSUSED*/
+static void
+doalarm(int)
+{
+	return;
+}
+
+
+/*
+ *	read_command_options(argc, argv)
+ *
+ *	Scan the cmd line options and process the ones that start with "-"
+ *
+ *	Return value:
+ *				-M argument, if any
+ *
+ *	Parameters:
+ *		argc		You know what this is
+ *		argv		You know what this is
+ *
+ *	Global variables used:
+ */
+static void
+read_command_options(register int argc, register char **argv)
+{
+	register int		ch;
+	int			current_optind = 1;
+	int			last_optind_with_double_hyphen = 0;
+	int			last_optind;
+	int			last_current_optind;
+	register int		i;
+	register int		j;
+	register int		k;
+	register int		makefile_next = 0; /*
+						    * flag to note options:
+						    * -c, f, g, j, m, o
+						    */
+	const char		*tptr;
+	const char		*CMD_OPTS;
+
+	extern char		*optarg;
+	extern int		optind, opterr, optopt;
+
+#define SUNPRO_CMD_OPTS	"-~Bbc:Ddef:g:ij:K:kM:m:NnO:o:PpqRrSsTtuVvwx:"
+
+#ifdef TEAMWARE_MAKE_CMN
+#	define SVR4_CMD_OPTS   "-c:ef:g:ij:km:nO:o:pqrsTtVv"
+#else
+#	define SVR4_CMD_OPTS   "-ef:iknpqrstV"
+#endif
+
+	/*
+	 * Added V in SVR4_CMD_OPTS also, which is going to be a hidden
+	 * option, just to make sure that the getopt doesn't fail when some
+	 * users leave their USE_SVR4_MAKE set and try to use the makefiles
+	 * that are designed to issue commands like $(MAKE) -V. Anyway it
+	 * sets the same flag but ensures that getopt doesn't fail.
+	 */
+
+	opterr = 0;
+	optind = 1;
+	while (1) {
+		last_optind=optind;			/* Save optind and current_optind values */
+		last_current_optind=current_optind;	/* in case we have to repeat this round. */
+		if (svr4) {
+			CMD_OPTS=SVR4_CMD_OPTS;
+			ch = getopt(argc, argv, SVR4_CMD_OPTS);
+		} else {
+			CMD_OPTS=SUNPRO_CMD_OPTS;
+			ch = getopt(argc, argv, SUNPRO_CMD_OPTS);
+		}
+		if (ch == EOF) {
+			if(optind < argc) {
+				/*
+				 * Fixing bug 4102537:
+				 *    Strange behaviour of command make using -- option.
+				 * Not all argv have been processed
+				 * Skip non-flag argv and continue processing.
+				 */
+				optind++;
+				current_optind++;
+				continue;
+			} else {
+				break;
+			}
+
+		}
+		if (ch == '?') {
+		 	if (optopt == '-') {
+				/* Bug 5060758: getopt() changed behavior (s10_60),
+				 * and now we have to deal with cases when options
+				 * with double hyphen appear here, from -$(MAKEFLAGS)
+				 */
+				i = current_optind;
+				if (argv[i][0] == '-') {
+				  if (argv[i][1] == '-') {
+				    if (argv[i][2] != '\0') {
+				      /* Check if this option is allowed */
+				      tptr = strchr(CMD_OPTS, argv[i][2]);
+				      if (tptr) {
+				        if (last_optind_with_double_hyphen != current_optind) {
+				          /* This is first time we are trying to fix "--"
+				           * problem with this option. If we come here second 
+				           * time, we will go to fatal error.
+				           */
+				          last_optind_with_double_hyphen = current_optind;
+				          
+				          /* Eliminate first hyphen character */
+				          for (j=0; argv[i][j] != '\0'; j++) {
+				            argv[i][j] = argv[i][j+1];
+				          }
+				          
+				          /* Repeat the processing of this argument */
+				          optind=last_optind;
+				          current_optind=last_current_optind;
+				          continue;
+				        }
+				      }
+				    }
+				  }
+				}
+			}
+		}
+
+		if (ch == '?') {
+			if (svr4) {
+#ifdef TEAMWARE_MAKE_CMN
+				fprintf(stderr,
+					catgets(catd, 1, 267, "Usage : dmake [ -f makefile ][ -c dmake_rcfile ][ -g dmake_group ]\n"));
+				fprintf(stderr,
+					catgets(catd, 1, 268, "              [ -j dmake_max_jobs ][ -m dmake_mode ][ -o dmake_odir ]...\n"));
+				fprintf(stderr,
+					catgets(catd, 1, 269, "              [ -e ][ -i ][ -k ][ -n ][ -p ][ -q ][ -r ][ -s ][ -t ][ -v ]\n"));
+#else
+				fprintf(stderr,
+					catgets(catd, 1, 270, "Usage : make [ -f makefile ]... [ -e ][ -i ][ -k ][ -n ][ -p ][ -q ][ -r ]\n"));
+				fprintf(stderr,
+					catgets(catd, 1, 271, "             [ -s ][ -t ]\n"));
+#endif
+				tptr = strchr(SVR4_CMD_OPTS, optopt);
+			} else {
+#ifdef TEAMWARE_MAKE_CMN
+				fprintf(stderr,
+					catgets(catd, 1, 272, "Usage : dmake [ -f makefile ][ -c dmake_rcfile ][ -g dmake_group ]\n"));
+				fprintf(stderr,
+					catgets(catd, 1, 273, "              [ -j dmake_max_jobs ][ -K statefile ][ -m dmake_mode ][ -x MODE_NAME=VALUE ][ -o dmake_odir ]...\n"));
+				fprintf(stderr,
+					catgets(catd, 1, 274, "              [ -d ][ -dd ][ -D ][ -DD ][ -e ][ -i ][ -k ][ -n ][ -p ][ -P ][ -u ][ -w ]\n"));
+				fprintf(stderr,
+					catgets(catd, 1, 275, "              [ -q ][ -r ][ -s ][ -S ][ -t ][ -v ][ -V ][ target... ][ macro=value... ][ \"macro +=value\"... ]\n"));
+#else
+				fprintf(stderr,
+					catgets(catd, 1, 276, "Usage : make [ -f makefile ][ -K statefile ]... [ -d ][ -dd ][ -D ][ -DD ]\n"));
+				fprintf(stderr,
+					catgets(catd, 1, 277, "             [ -e ][ -i ][ -k ][ -n ][ -p ][ -P ][ -q ][ -r ][ -s ][ -S ][ -t ]\n"));
+				fprintf(stderr,
+					catgets(catd, 1, 278, "             [ -u ][ -w ][ -V ][ target... ][ macro=value... ][ \"macro +=value\"... ]\n"));
+#endif
+				tptr = strchr(SUNPRO_CMD_OPTS, optopt);
+			}
+			if (!tptr) {
+				fatal(catgets(catd, 1, 279, "Unknown option `-%c'"), optopt);
+			} else {
+				fatal(catgets(catd, 1, 280, "Missing argument after `-%c'"), optopt);
+			}
+		}
+
+#if defined(linux)
+		if (ch == 1) {
+			if(optind < argc) {
+				//optind++;
+				//current_optind++;
+			makefile_next = 0;
+			current_optind = optind;
+				continue;
+			} else {
+				break;
+			}
+		}
+#endif
+
+
+		makefile_next |= parse_command_option(ch);
+		/*
+		 * If we're done processing all of the options of
+		 * ONE argument string...
+		 */
+		if (current_optind < optind) {
+			i = current_optind;
+			k = 0;
+			/* If there's an argument for an option... */
+			if ((optind - current_optind) > 1) {
+				k = i + 1;
+			}
+			switch (makefile_next) {
+			case 0:
+				argv[i] = NULL;
+				/* This shouldn't happen */
+				if (k) {
+					argv[k] = NULL;
+				}
+				break;
+			case 1:	/* -f seen */
+				argv[i] = NOCATGETS("-f");
+				break;
+			case 2:	/* -c seen */
+				argv[i] = NOCATGETS("-c");
+#ifndef TEAMWARE_MAKE_CMN
+				warning(catgets(catd, 1, 281, "Ignoring DistributedMake -c option"));
+#endif
+				break;
+			case 4:	/* -g seen */
+				argv[i] = NOCATGETS("-g");
+#ifndef TEAMWARE_MAKE_CMN
+				warning(catgets(catd, 1, 282, "Ignoring DistributedMake -g option"));
+#endif
+				break;
+			case 8:	/* -j seen */
+				argv[i] = NOCATGETS("-j");
+#ifndef TEAMWARE_MAKE_CMN
+				warning(catgets(catd, 1, 283, "Ignoring DistributedMake -j option"));
+#endif
+				break;
+			case 16: /* -M seen */
+				argv[i] = NOCATGETS("-M");
+#ifndef TEAMWARE_MAKE_CMN
+				warning(catgets(catd, 1, 284, "Ignoring ParallelMake -M option"));
+#endif
+				break;
+			case 32: /* -m seen */
+				argv[i] = NOCATGETS("-m");
+#ifndef TEAMWARE_MAKE_CMN
+				warning(catgets(catd, 1, 285, "Ignoring DistributedMake -m option"));
+#endif
+				break;
+#ifndef PARALLEL
+			case 128: /* -O seen */
+				argv[i] = NOCATGETS("-O");
+				break;
+#endif
+			case 256: /* -K seen */
+				argv[i] = NOCATGETS("-K");
+			        break;
+			case 512:	/* -o seen */
+				argv[i] = NOCATGETS("-o");
+#ifndef TEAMWARE_MAKE_CMN
+				warning(catgets(catd, 1, 311, "Ignoring DistributedMake -o option"));
+#endif
+				break;
+			case 1024: /* -x seen */
+				argv[i] = NOCATGETS("-x");
+#ifndef TEAMWARE_MAKE_CMN
+				warning(catgets(catd, 1, 353, "Ignoring DistributedMake -x option"));
+#endif
+				break;
+			default: /* > 1 of -c, f, g, j, K, M, m, O, o, x seen */
+				fatal(catgets(catd, 1, 286, "Illegal command line. More than one option requiring\nan argument given in the same argument group"));
+			}
+
+			makefile_next = 0;
+			current_optind = optind;
+		}
+	}
+}
+
+static void
+quote_str(char *str, char *qstr)
+{
+	char		*to;
+	char		*from;
+
+	to = qstr;
+	for (from = str; *from; from++) {
+		switch (*from) {
+		case ';':	/* End of command */
+		case '(':	/* Start group */
+		case ')':	/* End group */
+		case '{':	/* Start group */
+		case '}':	/* End group */
+		case '[':	/* Reg expr - any of a set of chars */
+		case ']':	/* End of set of chars */
+		case '|':	/* Pipe or logical-or */
+		case '^':	/* Old-fashioned pipe */
+		case '&':	/* Background or logical-and */
+		case '<':	/* Redirect stdin */
+		case '>':	/* Redirect stdout */
+		case '*':	/* Reg expr - any sequence of chars */
+		case '?':	/* Reg expr - any single char */
+		case '$':	/* Variable substitution */
+		case '\'':	/* Singe quote - turn off all magic */
+		case '"':	/* Double quote - span whitespace */
+		case '`':	/* Backquote - run a command */
+		case '#':	/* Comment */
+		case ' ':	/* Space (for MACRO=value1 value2  */
+		case '\\':	/* Escape char - turn off magic of next char */
+			*to++ = '\\';
+			break;
+
+		default:
+			break;
+		}
+		*to++ = *from;
+	}
+	*to = '\0';
+}
+
+static void
+unquote_str(char *str, char *qstr)
+{
+	char		*to;
+	char		*from;
+
+	to = qstr;
+	for (from = str; *from; from++) {
+		if (*from == '\\') {
+			from++;
+		}
+		*to++ = *from;
+	}
+	*to = '\0';
+}
+
+/*
+ * Convert the MAKEFLAGS string value into a vector of char *, similar
+ * to argv.
+ */
+static void
+setup_makeflags_argv()
+{
+	char		*cp;
+	char		*cp1;
+	char		*cp2;
+	char		*cp3;
+	char		*cp_orig;
+	Boolean		add_hyphen;
+	int		i;
+	char		tmp_char;
+
+	mf_argc = 1;
+	cp = getenv(makeflags->string_mb);
+	cp_orig = cp;
+
+	if (cp) {
+		/*
+		 * If new MAKEFLAGS format, no need to add hyphen.
+		 * If old MAKEFLAGS format, add hyphen before flags.
+		 */
+
+		if ((strchr(cp, (int) hyphen_char) != NULL) ||
+		    (strchr(cp, (int) equal_char) != NULL)) {
+
+			/* New MAKEFLAGS format */
+
+			add_hyphen = false;
+#ifdef ADDFIX5060758			
+			/* Check if MAKEFLAGS value begins with multiple
+			 * hyphen characters, and remove all duplicates.
+			 * Usually it happens when the next command is
+			 * used: $(MAKE) -$(MAKEFLAGS)
+			 * This is a workaround for BugID 5060758.
+			 */
+			while (*cp) {
+				if (*cp != (int) hyphen_char) {
+					break;
+				}
+				cp++;
+				if (*cp == (int) hyphen_char) {
+					/* There are two hyphens. Skip one */
+					cp_orig = cp;
+					cp++;
+				}
+				if (!(*cp)) {
+					/* There are hyphens only. Skip all */
+					cp_orig = cp;
+					break;
+				}
+			}
+#endif
+		} else {
+
+			/* Old MAKEFLAGS format */
+
+			add_hyphen = true;
+		}
+	}
+
+	/* Find the number of arguments in MAKEFLAGS */
+	while (cp && *cp) {
+		/* Skip white spaces */
+		while (cp && *cp && isspace(*cp)) {
+			cp++;
+		}
+		if (cp && *cp) {
+			/* Increment arg count */
+			mf_argc++;
+			/* Go to next white space */
+			while (cp && *cp && !isspace(*cp)) {
+				if(*cp == (int) backslash_char) {
+					cp++;
+				}
+				cp++;
+			}
+		}
+	}
+	/* Allocate memory for the new MAKEFLAGS argv */
+	mf_argv = (char **) malloc((mf_argc + 1) * sizeof(char *));
+	mf_argv[0] = NOCATGETS("MAKEFLAGS");
+	/*
+	 * Convert the MAKEFLAGS string value into a vector of char *,
+	 * similar to argv.
+	 */
+	cp = cp_orig;
+	for (i = 1; i < mf_argc; i++) {
+		/* Skip white spaces */
+		while (cp && *cp && isspace(*cp)) {
+			cp++;
+		}
+		if (cp && *cp) {
+			cp_orig = cp;
+			/* Go to next white space */
+			while (cp && *cp && !isspace(*cp)) {
+				if(*cp == (int) backslash_char) {
+					cp++;
+				}
+				cp++;
+			}
+			tmp_char = *cp;
+			*cp = (int) nul_char;
+			if (add_hyphen) {
+				mf_argv[i] = getmem(2 + strlen(cp_orig));
+				mf_argv[i][0] = '\0';
+				(void) strcat(mf_argv[i], "-");
+				// (void) strcat(mf_argv[i], cp_orig);
+				unquote_str(cp_orig, mf_argv[i]+1);
+			} else {
+				mf_argv[i] = getmem(2 + strlen(cp_orig));
+				//mf_argv[i] = strdup(cp_orig);
+				unquote_str(cp_orig, mf_argv[i]);
+			}
+			*cp = tmp_char;
+		}
+	}
+	mf_argv[i] = NULL;
+}
+
+/*
+ *	parse_command_option(ch)
+ *
+ *	Parse make command line options.
+ *
+ *	Return value:
+ *				Indicates if any -f -c or -M were seen
+ *
+ *	Parameters:
+ *		ch		The character to parse
+ *
+ *	Static variables used:
+ *		dmake_group_specified	Set for make -g
+ *		dmake_max_jobs_specified	Set for make -j
+ *		dmake_mode_specified	Set for make -m
+ *		dmake_add_mode_specified	Set for make -x
+ *		dmake_compat_mode_specified	Set for make -x SUN_MAKE_COMPAT_MODE=
+ *		dmake_output_mode_specified	Set for make -x DMAKE_OUTPUT_MODE=
+ *		dmake_odir_specified	Set for make -o
+ *		dmake_rcfile_specified	Set for make -c
+ *		env_wins		Set for make -e
+ *		ignore_default_mk	Set for make -r
+ *		trace_status		Set for make -p
+ *
+ *	Global variables used:
+ *		.make.state path & name set for make -K
+ *		continue_after_error	Set for make -k
+ *		debug_level		Set for make -d
+ *		do_not_exec_rule	Set for make -n
+ *		filter_stderr		Set for make -X
+ *		ignore_errors_all	Set for make -i
+ *		no_parallel		Set for make -R
+ *		quest			Set for make -q
+ *		read_trace_level	Set for make -D
+ *		report_dependencies	Set for make -P
+ *		send_mtool_msgs		Set for make -K
+ *		silent_all		Set for make -s
+ *		touch			Set for make -t
+ */
+static int
+parse_command_option(register char ch)
+{
+	static int		invert_next = 0;
+	int			invert_this = invert_next;
+
+	invert_next = 0;
+	switch (ch) {
+	case '-':			 /* Ignore "--" */
+		return 0;
+	case '~':			 /* Invert next option */
+		invert_next = 1;
+		return 0;
+	case 'B':			 /* Obsolete */
+		return 0;
+	case 'b':			 /* Obsolete */
+		return 0;
+	case 'c':			 /* Read alternative dmakerc file */
+		if (invert_this) {
+			dmake_rcfile_specified = false;
+		} else {
+			dmake_rcfile_specified = true;
+		}
+		return 2;
+	case 'D':			 /* Show lines read */
+		if (invert_this) {
+			read_trace_level--;
+		} else {
+			read_trace_level++;
+		}
+		return 0;
+	case 'd':			 /* Debug flag */
+		if (invert_this) {
+			debug_level--;
+		} else {
+#if defined( HP_UX) || defined(linux)
+		      if (debug_level < 2)  /* Fixes a bug on HP-UX */
+#endif
+			debug_level++;
+		}
+		return 0;
+#ifdef NSE
+	case 'E':
+		if (invert_this) {
+			nse = false;
+		} else {
+			nse = true;
+		}
+		nse_init_source_suffixes();
+		return 0;
+#endif
+	case 'e':			 /* Environment override flag */
+		if (invert_this) {
+			env_wins = false;
+		} else {
+			env_wins = true;
+		}
+		return 0;
+	case 'f':			 /* Read alternative makefile(s) */
+		return 1;
+	case 'g':			 /* Use alternative DMake group */
+		if (invert_this) {
+			dmake_group_specified = false;
+		} else {
+			dmake_group_specified = true;
+		}
+		return 4;
+	case 'i':			 /* Ignore errors */
+		if (invert_this) {
+			ignore_errors_all = false;
+		} else {
+			ignore_errors_all = true;
+		}
+		return 0;
+	case 'j':			 /* Use alternative DMake max jobs */
+		if (invert_this) {
+			dmake_max_jobs_specified = false;
+		} else {
+			dmake_max_jobs_specified = true;
+		}
+		return 8;
+	case 'K':			 /* Read alternative .make.state */
+		return 256;
+	case 'k':			 /* Keep making even after errors */
+		if (invert_this) {
+			continue_after_error = false;
+		} else {
+			continue_after_error = true;
+			continue_after_error_ever_seen = true;
+		}
+		return 0;
+	case 'M':			 /* Read alternative make.machines file */
+		if (invert_this) {
+			pmake_machinesfile_specified = false;
+		} else {
+			pmake_machinesfile_specified = true;
+			dmake_mode_type = parallel_mode;
+			no_parallel = false;
+		}
+		return 16;
+	case 'm':			 /* Use alternative DMake build mode */
+		if (invert_this) {
+			dmake_mode_specified = false;
+		} else {
+			dmake_mode_specified = true;
+		}
+		return 32;
+	case 'x':			 /* Use alternative DMake mode */
+		if (invert_this) {
+			dmake_add_mode_specified = false;
+		} else {
+			dmake_add_mode_specified = true;
+		}
+		return 1024;
+	case 'N':			 /* Reverse -n */
+		if (invert_this) {
+			do_not_exec_rule = true;
+		} else {
+			do_not_exec_rule = false;
+		}
+		return 0;
+	case 'n':			 /* Print, not exec commands */
+		if (invert_this) {
+			do_not_exec_rule = false;
+		} else {
+			do_not_exec_rule = true;
+		}
+		return 0;
+#ifndef PARALLEL
+	case 'O':			 /* Send job start & result msgs */
+		if (invert_this) {
+			send_mtool_msgs = false;
+		} else {
+#ifdef DISTRIBUTED
+			send_mtool_msgs = true;
+#endif
+		}
+		return 128;
+#endif
+	case 'o':			 /* Use alternative dmake output dir */
+		if (invert_this) {
+			dmake_odir_specified = false;
+		} else {
+			dmake_odir_specified = true;
+		}
+		return 512;
+	case 'P':			 /* Print for selected targets */
+		if (invert_this) {
+			report_dependencies_level--;
+		} else {
+			report_dependencies_level++;
+		}
+		return 0;
+	case 'p':			 /* Print description */
+		if (invert_this) {
+			trace_status = false;
+			do_not_exec_rule = false;
+		} else {
+			trace_status = true;
+			do_not_exec_rule = true;
+		}
+		return 0;
+	case 'q':			 /* Question flag */
+		if (invert_this) {
+			quest = false;
+		} else {
+			quest = true;
+		}
+		return 0;
+	case 'R':			 /* Don't run in parallel */
+#ifdef TEAMWARE_MAKE_CMN
+		if (invert_this) {
+			pmake_cap_r_specified = false;
+			no_parallel = false;
+		} else {
+			pmake_cap_r_specified = true;
+			dmake_mode_type = serial_mode;
+			no_parallel = true;
+		}
+#else
+		warning(catgets(catd, 1, 182, "Ignoring ParallelMake -R option"));
+#endif
+		return 0;
+	case 'r':			 /* Turn off internal rules */
+		if (invert_this) {
+			ignore_default_mk = false;
+		} else {
+			ignore_default_mk = true;
+		}
+		return 0;
+	case 'S':			 /* Reverse -k */
+		if (invert_this) {
+			continue_after_error = true;
+		} else {
+			continue_after_error = false;
+			stop_after_error_ever_seen = true;
+		}
+		return 0;
+	case 's':			 /* Silent flag */
+		if (invert_this) {
+			silent_all = false;
+		} else {
+			silent_all = true;
+		}
+		return 0;
+	case 'T':			 /* Print target list */
+		if (invert_this) {
+			list_all_targets = false;
+			do_not_exec_rule = false;
+		} else {
+			list_all_targets = true;
+			do_not_exec_rule = true;
+		}
+		return 0;
+	case 't':			 /* Touch flag */
+		if (invert_this) {
+			touch = false;
+		} else {
+			touch = true;
+		}
+		return 0;
+	case 'u':			 /* Unconditional flag */
+		if (invert_this) {
+			build_unconditional = false;
+		} else {
+			build_unconditional = true;
+		}
+		return 0;
+	case 'V':			/* SVR4 mode */
+		svr4 = true;
+		return 0;
+	case 'v':			/* Version flag */
+		if (invert_this) {
+		} else {
+#ifdef TEAMWARE_MAKE_CMN
+			fprintf(stdout, NOCATGETS("dmake: %s\n"), verstring);
+#ifdef SUN5_0
+			exit_status = 0;
+#endif
+			exit(0);
+#else
+			warning(catgets(catd, 1, 324, "Ignoring DistributedMake -v option"));
+#endif
+		}
+		return 0;
+	case 'w':			 /* Unconditional flag */
+		if (invert_this) {
+			report_cwd = false;
+		} else {
+			report_cwd = true;
+		}
+		return 0;
+#if 0
+	case 'X':			/* Filter stdout */
+		if (invert_this) {
+			filter_stderr = false;
+		} else {
+			filter_stderr = true;
+		}
+		return 0;
+#endif
+	default:
+		break;
+	}
+	return 0;
+}
+
+/*
+ *	setup_for_projectdir()
+ *
+ *	Read the PROJECTDIR variable, if defined, and set the sccs path
+ *
+ *	Parameters:
+ *
+ *	Global variables used:
+ *		sccs_dir_path	Set to point to SCCS dir to use
+ */
+static void
+setup_for_projectdir(void)
+{
+static char	path[MAXPATHLEN];
+char		cwdpath[MAXPATHLEN];
+uid_t uid;
+int   done=0;
+
+	/* Check if we should use PROJECTDIR when reading the SCCS dir. */
+	sccs_dir_path = getenv(NOCATGETS("PROJECTDIR"));
+	if ((sccs_dir_path != NULL) &&
+	    (sccs_dir_path[0] != (int) slash_char)) {
+		struct passwd *pwent;
+
+	     {
+		uid = getuid();
+		pwent = getpwuid(uid);
+		if (pwent == NULL) {
+		   fatal(catgets(catd, 1, 188, "Bogus USERID "));
+		}
+		if ((pwent = getpwnam(sccs_dir_path)) == NULL) {
+			/*empty block : it'll go & check cwd  */
+		}
+		else {
+		  (void) sprintf(path, NOCATGETS("%s/src"), pwent->pw_dir);
+		  if (access(path, F_OK) == 0) {
+			sccs_dir_path = path;
+			done = 1;
+		  } else {
+			(void) sprintf(path, NOCATGETS("%s/source"), pwent->pw_dir);
+			if (access(path, F_OK) == 0) {
+				sccs_dir_path = path;
+				done = 1;
+			}
+		     }
+		}
+		if (!done) {
+		    if (getcwd(cwdpath, MAXPATHLEN - 1 )) {
+
+		       (void) sprintf(path, NOCATGETS("%s/%s"), cwdpath,sccs_dir_path);
+		       if (access(path, F_OK) == 0) {
+		        	sccs_dir_path = path;
+				done = 1;
+		        } else {
+		  	       	fatal(catgets(catd, 1, 189, "Bogus PROJECTDIR '%s'"), sccs_dir_path);
+		        }
+		    }
+		}
+	   }
+	}
+}
+
+/*
+ *	set_sgs_support()
+ *
+ *	Add the libmakestate.so.1 lib to the env var SGS_SUPPORT
+ *	  if it's not already in there.
+ *	The SGS_SUPPORT env var and libmakestate.so.1 is used by
+ *	  the linker ld to report .make.state info back to make.
+ */
+static void
+set_sgs_support()
+{
+	int		len;
+	char		*newpath;
+	char		*oldpath;
+	static char	*prev_path;
+
+	oldpath = getenv(LD_SUPPORT_ENV_VAR);
+	if (oldpath == NULL) {
+		len = strlen(LD_SUPPORT_ENV_VAR) + 1 +
+			strlen(LD_SUPPORT_MAKE_LIB) + 1;
+		newpath = (char *) malloc(len);
+		sprintf(newpath, "%s=", LD_SUPPORT_ENV_VAR);
+	} else {
+		len = strlen(LD_SUPPORT_ENV_VAR) + 1 + strlen(oldpath) + 1 +
+			strlen(LD_SUPPORT_MAKE_LIB) + 1;
+		newpath = (char *) malloc(len);
+		sprintf(newpath, "%s=%s", LD_SUPPORT_ENV_VAR, oldpath);
+	}
+
+#if defined(TEAMWARE_MAKE_CMN)
+
+	/* function maybe_append_str_to_env_var() is defined in avo_util library
+	 * Serial make should not use this library !!!
+	 */
+	maybe_append_str_to_env_var(newpath, LD_SUPPORT_MAKE_LIB);
+#else
+	if (oldpath == NULL) {
+		sprintf(newpath, "%s%s", newpath, LD_SUPPORT_MAKE_LIB);
+	} else {
+		sprintf(newpath, "%s:%s", newpath, LD_SUPPORT_MAKE_LIB);
+	}
+#endif
+	putenv(newpath);
+	if (prev_path) {
+		free(prev_path);
+	}
+	prev_path = newpath;
+}
+
+/*
+ *	read_files_and_state(argc, argv)
+ *
+ *	Read the makefiles we care about and the environment
+ *	Also read the = style command line options
+ *
+ *	Parameters:
+ *		argc		You know what this is
+ *		argv		You know what this is
+ *
+ *	Static variables used:
+ *		env_wins	make -e, determines if env vars are RO
+ *		ignore_default_mk make -r, determines if make.rules is read
+ *		not_auto_depen	dwight
+ *
+ *	Global variables used:
+ *		default_target_to_build	Set to first proper target from file
+ *		do_not_exec_rule Set to false when makfile is made
+ *		dot		The Name ".", used to read current dir
+ *		empty_name	The Name "", use as macro value
+ *		keep_state	Set if KEEP_STATE is in environment
+ *		make_state	The Name ".make.state", used to read file
+ *		makefile_type	Set to type of file being read
+ *		makeflags	The Name "MAKEFLAGS", used to set macro value
+ *		not_auto	dwight
+ *		nse		Set if NSE_ENV is in the environment
+ *		read_trace_level Checked to se if the reader should trace
+ *		report_dependencies If -P is on we do not read .make.state
+ *		trace_reader	Set if reader should trace
+ *		virtual_root	The Name "VIRTUAL_ROOT", used to check value
+ */
+static void
+read_files_and_state(int argc, char **argv)
+{
+	wchar_t			buffer[1000];
+	wchar_t			buffer_posix[1000];
+	register char		ch;
+	register char		*cp;
+	Property		def_make_macro = NULL;
+	Name			def_make_name;
+	Name			default_makefile;
+	String_rec		dest;
+	wchar_t			destbuffer[STRING_BUFFER_LENGTH];
+	register int		i;
+	register int		j;
+	Name			keep_state_name;
+	int			length;
+	Name			Makefile;
+	register Property	macro;
+	struct stat		make_state_stat;
+	Name			makefile_name;
+        register int		makefile_next = 0;
+	register Boolean	makefile_read = false;
+	String_rec		makeflags_string;
+	String_rec		makeflags_string_posix;
+	String_rec *		makeflags_string_current;
+	Name			makeflags_value_saved;
+	register Name		name;
+	Name			new_make_value;
+	Boolean			save_do_not_exec_rule;
+	Name			sdotMakefile;
+	Name			sdotmakefile_name;
+	static wchar_t		state_file_str;
+	static char		state_file_str_mb[MAXPATHLEN];
+	static struct _Name	state_filename;
+	Boolean			temp;
+	char			tmp_char;
+	wchar_t			*tmp_wcs_buffer;
+	register Name		value;
+	ASCII_Dyn_Array		makeflags_and_macro;
+	Boolean			is_xpg4;
+
+/*
+ *	Remember current mode. It may be changed after reading makefile
+ *	and we will have to correct MAKEFLAGS variable.
+ */
+	is_xpg4 = posix;
+
+	MBSTOWCS(wcs_buffer, NOCATGETS("KEEP_STATE"));
+	keep_state_name = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS("Makefile"));
+	Makefile = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS("makefile"));
+	makefile_name = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS("s.makefile"));
+	sdotmakefile_name = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS("s.Makefile"));
+	sdotMakefile = GETNAME(wcs_buffer, FIND_LENGTH);
+
+/*
+ *	Set flag if NSE is active
+ */
+#ifdef NSE
+	if (getenv(NOCATGETS("NSE_ENV")) != NULL) {
+		nse = true;
+	}
+#endif
+
+/*
+ *	initialize global dependency entry for .NOT_AUTO
+ */
+	not_auto_depen->next = NULL;
+	not_auto_depen->name = not_auto;
+	not_auto_depen->automatic = not_auto_depen->stale = false;
+
+/*
+ *	Read internal definitions and rules.
+ */
+	if (read_trace_level > 1) {
+		trace_reader = true;
+	}
+	if (!ignore_default_mk) {
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+		if (svr4) {
+			MBSTOWCS(wcs_buffer, NOCATGETS("svr4.make.rules"));
+			default_makefile = GETNAME(wcs_buffer, FIND_LENGTH);
+		} else {
+			MBSTOWCS(wcs_buffer, NOCATGETS("make.rules"));
+			default_makefile = GETNAME(wcs_buffer, FIND_LENGTH);
+		}
+#else		
+		MBSTOWCS(wcs_buffer, NOCATGETS("default.mk"));
+		default_makefile = GETNAME(wcs_buffer, FIND_LENGTH);
+#endif
+		default_makefile->stat.is_file = true;
+
+		(void) read_makefile(default_makefile,
+				     true,
+				     false,
+				     true);
+	}
+
+	/*
+	 * If the user did not redefine the MAKE macro in the
+	 * default makefile (make.rules), then we'd like to
+	 * change the macro value of MAKE to be some form
+	 * of argv[0] for recursive MAKE builds.
+	 */
+	MBSTOWCS(wcs_buffer, NOCATGETS("MAKE"));
+	def_make_name = GETNAME(wcs_buffer, wslen(wcs_buffer));
+	def_make_macro = get_prop(def_make_name->prop, macro_prop);
+	if ((def_make_macro != NULL) &&
+	    (IS_EQUAL(def_make_macro->body.macro.value->string_mb,
+	              NOCATGETS("make")))) {
+		MBSTOWCS(wcs_buffer, argv_zero_string);
+		new_make_value = GETNAME(wcs_buffer, wslen(wcs_buffer));
+		(void) SETVAR(def_make_name,
+		              new_make_value,
+		              false);
+	}
+
+	default_target_to_build = NULL;
+	trace_reader = false;
+
+/*
+ *	Read environment args. Let file args which follow override unless
+ *	-e option seen. If -e option is not mentioned.
+ */
+	read_environment(env_wins);
+	if (getvar(virtual_root)->hash.length == 0) {
+		maybe_append_prop(virtual_root, macro_prop)
+		  ->body.macro.exported = true;
+		MBSTOWCS(wcs_buffer, "/");
+		(void) SETVAR(virtual_root,
+			      GETNAME(wcs_buffer, FIND_LENGTH),
+			      false);
+	}
+
+/*
+ * We now scan mf_argv and argv to see if we need to set
+ * any of the DMake-added options/variables in MAKEFLAGS.
+ */
+
+	makeflags_and_macro.start = 0;
+	makeflags_and_macro.size = 0;
+	enter_argv_values(mf_argc, mf_argv, &makeflags_and_macro);
+	enter_argv_values(argc, argv, &makeflags_and_macro);
+
+/*
+ *	Set MFLAGS and MAKEFLAGS
+ *	
+ *	Before reading makefile we do not know exactly which mode
+ *	(posix or not) is used. So prepare two MAKEFLAGS strings
+ *	for both posix and solaris modes because they are different.
+ */
+	INIT_STRING_FROM_STACK(makeflags_string, buffer);
+	INIT_STRING_FROM_STACK(makeflags_string_posix, buffer_posix);
+	append_char((int) hyphen_char, &makeflags_string);
+	append_char((int) hyphen_char, &makeflags_string_posix);
+
+	switch (read_trace_level) {
+	case 2:
+		append_char('D', &makeflags_string);
+		append_char('D', &makeflags_string_posix);
+	case 1:
+		append_char('D', &makeflags_string);
+		append_char('D', &makeflags_string_posix);
+	}
+	switch (debug_level) {
+	case 2:
+		append_char('d', &makeflags_string);
+		append_char('d', &makeflags_string_posix);
+	case 1:
+		append_char('d', &makeflags_string);
+		append_char('d', &makeflags_string_posix);
+	}
+#ifdef NSE
+	if (nse) {
+		append_char('E', &makeflags_string);
+	}
+#endif
+	if (env_wins) {
+		append_char('e', &makeflags_string);
+		append_char('e', &makeflags_string_posix);
+	}
+	if (ignore_errors_all) {
+		append_char('i', &makeflags_string);
+		append_char('i', &makeflags_string_posix);
+	}
+	if (continue_after_error) {
+		if (stop_after_error_ever_seen) {
+			append_char('S', &makeflags_string_posix);
+			append_char((int) space_char, &makeflags_string_posix);
+			append_char((int) hyphen_char, &makeflags_string_posix);
+		}
+		append_char('k', &makeflags_string);
+		append_char('k', &makeflags_string_posix);
+	} else {
+		if (stop_after_error_ever_seen 
+		    && continue_after_error_ever_seen) {
+			append_char('k', &makeflags_string_posix);
+			append_char((int) space_char, &makeflags_string_posix);
+			append_char((int) hyphen_char, &makeflags_string_posix);
+			append_char('S', &makeflags_string_posix);
+		}
+	}
+	if (do_not_exec_rule) {
+		append_char('n', &makeflags_string);
+		append_char('n', &makeflags_string_posix);
+	}
+	switch (report_dependencies_level) {
+	case 4:
+		append_char('P', &makeflags_string);
+		append_char('P', &makeflags_string_posix);
+	case 3:
+		append_char('P', &makeflags_string);
+		append_char('P', &makeflags_string_posix);
+	case 2:
+		append_char('P', &makeflags_string);
+		append_char('P', &makeflags_string_posix);
+	case 1:
+		append_char('P', &makeflags_string);
+		append_char('P', &makeflags_string_posix);
+	}
+	if (trace_status) {
+		append_char('p', &makeflags_string);
+		append_char('p', &makeflags_string_posix);
+	}
+	if (quest) {
+		append_char('q', &makeflags_string);
+		append_char('q', &makeflags_string_posix);
+	}
+	if (silent_all) {
+		append_char('s', &makeflags_string);
+		append_char('s', &makeflags_string_posix);
+	}
+	if (touch) {
+		append_char('t', &makeflags_string);
+		append_char('t', &makeflags_string_posix);
+	}
+	if (build_unconditional) {
+		append_char('u', &makeflags_string);
+		append_char('u', &makeflags_string_posix);
+	}
+	if (report_cwd) {
+		append_char('w', &makeflags_string);
+		append_char('w', &makeflags_string_posix);
+	}
+#ifndef PARALLEL
+	/* -c dmake_rcfile */
+	if (dmake_rcfile_specified) {
+		MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_RCFILE"));
+		dmake_rcfile = GETNAME(wcs_buffer, FIND_LENGTH);
+		append_makeflags_string(dmake_rcfile, &makeflags_string);
+		append_makeflags_string(dmake_rcfile, &makeflags_string_posix);
+	}
+	/* -g dmake_group */
+	if (dmake_group_specified) {
+		MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_GROUP"));
+		dmake_group = GETNAME(wcs_buffer, FIND_LENGTH);
+		append_makeflags_string(dmake_group, &makeflags_string);
+		append_makeflags_string(dmake_group, &makeflags_string_posix);
+	}
+	/* -j dmake_max_jobs */
+	if (dmake_max_jobs_specified) {
+		MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MAX_JOBS"));
+		dmake_max_jobs = GETNAME(wcs_buffer, FIND_LENGTH);
+		append_makeflags_string(dmake_max_jobs, &makeflags_string);
+		append_makeflags_string(dmake_max_jobs, &makeflags_string_posix);
+	}
+	/* -m dmake_mode */
+	if (dmake_mode_specified) {
+		MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MODE"));
+		dmake_mode = GETNAME(wcs_buffer, FIND_LENGTH);
+		append_makeflags_string(dmake_mode, &makeflags_string);
+		append_makeflags_string(dmake_mode, &makeflags_string_posix);
+	}
+	/* -x dmake_compat_mode */
+//	if (dmake_compat_mode_specified) {
+//		MBSTOWCS(wcs_buffer, NOCATGETS("SUN_MAKE_COMPAT_MODE"));
+//		dmake_compat_mode = GETNAME(wcs_buffer, FIND_LENGTH);
+//		append_makeflags_string(dmake_compat_mode, &makeflags_string);
+//		append_makeflags_string(dmake_compat_mode, &makeflags_string_posix);
+//	}
+	/* -x dmake_output_mode */
+	if (dmake_output_mode_specified) {
+		MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_OUTPUT_MODE"));
+		dmake_output_mode = GETNAME(wcs_buffer, FIND_LENGTH);
+		append_makeflags_string(dmake_output_mode, &makeflags_string);
+		append_makeflags_string(dmake_output_mode, &makeflags_string_posix);
+	}
+	/* -o dmake_odir */
+	if (dmake_odir_specified) {
+		MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_ODIR"));
+		dmake_odir = GETNAME(wcs_buffer, FIND_LENGTH);
+		append_makeflags_string(dmake_odir, &makeflags_string);
+		append_makeflags_string(dmake_odir, &makeflags_string_posix);
+	}
+	/* -M pmake_machinesfile */
+	if (pmake_machinesfile_specified) {
+		MBSTOWCS(wcs_buffer, NOCATGETS("PMAKE_MACHINESFILE"));
+		pmake_machinesfile = GETNAME(wcs_buffer, FIND_LENGTH);
+		append_makeflags_string(pmake_machinesfile, &makeflags_string);
+		append_makeflags_string(pmake_machinesfile, &makeflags_string_posix);
+	}
+	/* -R */
+	if (pmake_cap_r_specified) {
+		append_char((int) space_char, &makeflags_string);
+		append_char((int) hyphen_char, &makeflags_string);
+		append_char('R', &makeflags_string);
+		append_char((int) space_char, &makeflags_string_posix);
+		append_char((int) hyphen_char, &makeflags_string_posix);
+		append_char('R', &makeflags_string_posix);
+	}
+#endif
+
+/*
+ *	Make sure MAKEFLAGS is exported
+ */
+	maybe_append_prop(makeflags, macro_prop)->
+	  body.macro.exported = true;
+
+	if (makeflags_string.buffer.start[1] != (int) nul_char) {
+		if (makeflags_string.buffer.start[1] != (int) space_char) {
+			MBSTOWCS(wcs_buffer, NOCATGETS("MFLAGS"));
+			(void) SETVAR(GETNAME(wcs_buffer, FIND_LENGTH),
+				      GETNAME(makeflags_string.buffer.start,
+					      FIND_LENGTH),
+				      false);
+		} else {
+			MBSTOWCS(wcs_buffer, NOCATGETS("MFLAGS"));
+			(void) SETVAR(GETNAME(wcs_buffer, FIND_LENGTH),
+				      GETNAME(makeflags_string.buffer.start + 2,
+					      FIND_LENGTH),
+				      false);
+		}
+	}
+
+/* 
+ *	Add command line macro to POSIX makeflags_string  
+ */
+	if (makeflags_and_macro.start) {
+		tmp_char = (char) space_char;
+		cp = makeflags_and_macro.start;
+		do {
+			append_char(tmp_char, &makeflags_string_posix);
+		} while ( tmp_char = *cp++ ); 
+		retmem_mb(makeflags_and_macro.start);
+	}
+
+/*
+ *	Now set the value of MAKEFLAGS macro in accordance
+ *	with current mode.
+ */
+	macro = maybe_append_prop(makeflags, macro_prop);
+	temp = (Boolean) macro->body.macro.read_only;
+	macro->body.macro.read_only = false;
+	if(posix || gnu_style) {
+		makeflags_string_current = &makeflags_string_posix;
+	} else {
+		makeflags_string_current = &makeflags_string;
+	}
+	if (makeflags_string_current->buffer.start[1] == (int) nul_char) {
+		makeflags_value_saved =
+			GETNAME( makeflags_string_current->buffer.start + 1
+			       , FIND_LENGTH
+			       );
+	} else {
+		if (makeflags_string_current->buffer.start[1] != (int) space_char) {
+			makeflags_value_saved =
+				GETNAME( makeflags_string_current->buffer.start
+				       , FIND_LENGTH
+				       );
+		} else {
+			makeflags_value_saved =
+				GETNAME( makeflags_string_current->buffer.start + 2
+				       , FIND_LENGTH
+				       );
+		}
+	}
+	(void) SETVAR( makeflags
+	             , makeflags_value_saved
+	             , false
+	             );
+	macro->body.macro.read_only = temp;
+
+/*
+ *	Read command line "-f" arguments and ignore -c, g, j, K, M, m, O and o args.
+ */
+	save_do_not_exec_rule = do_not_exec_rule;
+	do_not_exec_rule = false;
+	if (read_trace_level > 0) {
+		trace_reader = true;
+	}
+
+	for (i = 1; i < argc; i++) {
+		if (argv[i] &&
+		    (argv[i][0] == (int) hyphen_char) &&
+		    (argv[i][1] == 'f') &&
+		    (argv[i][2] == (int) nul_char)) {
+			argv[i] = NULL;		/* Remove -f */
+			if (i >= argc - 1) {
+				fatal(catgets(catd, 1, 190, "No filename argument after -f flag"));
+			}
+			MBSTOWCS(wcs_buffer, argv[++i]);
+			primary_makefile = GETNAME(wcs_buffer, FIND_LENGTH);
+			(void) read_makefile(primary_makefile, true, true, true);
+			argv[i] = NULL;		/* Remove filename */
+			makefile_read = true;
+		} else if (argv[i] &&
+			   (argv[i][0] == (int) hyphen_char) &&
+			   (argv[i][1] == 'c' ||
+			    argv[i][1] == 'g' ||
+			    argv[i][1] == 'j' ||
+			    argv[i][1] == 'K' ||
+			    argv[i][1] == 'M' ||
+			    argv[i][1] == 'm' ||
+			    argv[i][1] == 'O' ||
+			    argv[i][1] == 'o') &&
+			   (argv[i][2] == (int) nul_char)) {
+			argv[i] = NULL;
+			argv[++i] = NULL;
+		}
+	}
+
+/*
+ *	If no command line "-f" args then look for "makefile", and then for
+ *	"Makefile" if "makefile" isn't found.
+ */
+	if (!makefile_read) {
+		(void) read_dir(dot,
+				(wchar_t *) NULL,
+				(Property) NULL,
+				(wchar_t *) NULL);
+	    if (!posix) {
+		if (makefile_name->stat.is_file) {
+			if (Makefile->stat.is_file) {
+				warning(catgets(catd, 1, 310, "Both `makefile' and `Makefile' exist"));
+			}
+			primary_makefile = makefile_name;
+			makefile_read = read_makefile(makefile_name,
+						      false,
+						      false,
+						      true);
+		}
+		if (!makefile_read &&
+		    Makefile->stat.is_file) {
+			primary_makefile = Makefile;
+			makefile_read = read_makefile(Makefile,
+						      false,
+						      false,
+						      true);
+		}
+	    } else {
+
+		enum sccs_stat save_m_has_sccs = NO_SCCS;
+		enum sccs_stat save_M_has_sccs = NO_SCCS;
+
+		if (makefile_name->stat.is_file) {
+			if (Makefile->stat.is_file) {
+				warning(catgets(catd, 1, 191, "Both `makefile' and `Makefile' exist"));
+			}
+		}
+		if (makefile_name->stat.is_file) {
+			if (makefile_name->stat.has_sccs == NO_SCCS) {
+			   primary_makefile = makefile_name;
+			   makefile_read = read_makefile(makefile_name,
+						      false,
+						      false,
+						      true);
+			} else {
+			  save_m_has_sccs = makefile_name->stat.has_sccs;
+			  makefile_name->stat.has_sccs = NO_SCCS;
+			  primary_makefile = makefile_name;
+			  makefile_read = read_makefile(makefile_name,
+						      false,
+						      false,
+						      true);
+			}
+		}
+		if (!makefile_read &&
+		    Makefile->stat.is_file) {
+			if (Makefile->stat.has_sccs == NO_SCCS) {
+			   primary_makefile = Makefile;
+			   makefile_read = read_makefile(Makefile,
+						      false,
+						      false,
+						      true);
+			} else {
+			  save_M_has_sccs = Makefile->stat.has_sccs;
+			  Makefile->stat.has_sccs = NO_SCCS;
+			  primary_makefile = Makefile;
+			  makefile_read = read_makefile(Makefile,
+						      false,
+						      false,
+						      true);
+			}
+		}
+		if (!makefile_read &&
+		        makefile_name->stat.is_file) {
+			   makefile_name->stat.has_sccs = save_m_has_sccs;
+			   primary_makefile = makefile_name;
+			   makefile_read = read_makefile(makefile_name,
+						      false,
+						      false,
+						      true);
+		}
+		if (!makefile_read &&
+		    Makefile->stat.is_file) {
+			   Makefile->stat.has_sccs = save_M_has_sccs;
+			   primary_makefile = Makefile;
+			   makefile_read = read_makefile(Makefile,
+						      false,
+						      false,
+						      true);
+		}
+	    }
+	}
+	do_not_exec_rule = save_do_not_exec_rule;
+	allrules_read = makefile_read;
+	trace_reader = false;
+
+/*
+ *	Now get current value of MAKEFLAGS and compare it with
+ *	the saved value we set before reading makefile.
+ *	If they are different then MAKEFLAGS is subsequently set by
+ *	makefile, just leave it there. Otherwise, if make mode
+ *	is changed by using .POSIX target in makefile we need
+ *	to correct MAKEFLAGS value.
+ */
+	Name mf_val = getvar(makeflags);
+	if( (posix != is_xpg4)
+	 && (!strcmp(mf_val->string_mb, makeflags_value_saved->string_mb)))
+	{
+		if (makeflags_string_posix.buffer.start[1] == (int) nul_char) {
+			(void) SETVAR(makeflags,
+				      GETNAME(makeflags_string_posix.buffer.start + 1,
+					      FIND_LENGTH),
+				      false);
+		} else {
+			if (makeflags_string_posix.buffer.start[1] != (int) space_char) {
+				(void) SETVAR(makeflags,
+					      GETNAME(makeflags_string_posix.buffer.start,
+						      FIND_LENGTH),
+					      false);
+			} else {
+				(void) SETVAR(makeflags,
+					      GETNAME(makeflags_string_posix.buffer.start + 2,
+						      FIND_LENGTH),
+					      false);
+			}
+		}
+	}
+
+	if (makeflags_string.free_after_use) {
+		retmem(makeflags_string.buffer.start);
+	}
+	if (makeflags_string_posix.free_after_use) {
+		retmem(makeflags_string_posix.buffer.start);
+	}
+	makeflags_string.buffer.start = NULL;
+	makeflags_string_posix.buffer.start = NULL;
+
+	if (posix) {
+		/*
+		 * If the user did not redefine the ARFLAGS macro in the
+		 * default makefile (make.rules), then we'd like to
+		 * change the macro value of ARFLAGS to be in accordance
+		 * with "POSIX" requirements.
+		 */
+		MBSTOWCS(wcs_buffer, NOCATGETS("ARFLAGS"));
+		name = GETNAME(wcs_buffer, wslen(wcs_buffer));
+		macro = get_prop(name->prop, macro_prop);
+		if ((macro != NULL) && /* Maybe (macro == NULL) || ? */
+		    (IS_EQUAL(macro->body.macro.value->string_mb,
+		              NOCATGETS("rv")))) {
+			MBSTOWCS(wcs_buffer, NOCATGETS("-rv"));
+			value = GETNAME(wcs_buffer, wslen(wcs_buffer));
+			(void) SETVAR(name,
+			              value,
+			              false);
+		}
+	}
+
+	if (!posix && !svr4) {
+		set_sgs_support();
+	}
+
+
+/*
+ *	Make sure KEEP_STATE is in the environment if KEEP_STATE is on.
+ */
+	macro = get_prop(keep_state_name->prop, macro_prop);
+	if ((macro != NULL) &&
+	    macro->body.macro.exported) {
+		keep_state = true;
+	}
+	if (keep_state) {
+		if (macro == NULL) {
+			macro = maybe_append_prop(keep_state_name,
+						  macro_prop);
+		}
+		macro->body.macro.exported = true;
+		(void) SETVAR(keep_state_name,
+			      empty_name,
+			      false);
+
+		/*
+		 *	Read state file
+		 */
+
+		/* Before we read state, let's make sure we have
+		** right state file.
+		*/
+		/* just in case macro references are used in make_state file
+		** name, we better expand them at this stage using expand_value.
+		*/
+		INIT_STRING_FROM_STACK(dest, destbuffer);
+		expand_value(make_state, &dest, false);
+
+		make_state = GETNAME(dest.buffer.start, FIND_LENGTH);
+
+		if(!stat(make_state->string_mb, &make_state_stat)) {
+		   if(!(make_state_stat.st_mode & S_IFREG) ) {
+			/* copy the make_state structure to the other
+			** and then let make_state point to the new
+			** one.
+			*/
+		      memcpy(&state_filename, make_state,sizeof(state_filename));
+		      state_filename.string_mb = state_file_str_mb;
+		/* Just a kludge to avoid two slashes back to back */			
+		      if((make_state->hash.length == 1)&&
+			        (make_state->string_mb[0] == '/')) {
+			 make_state->hash.length = 0;
+			 make_state->string_mb[0] = '\0';
+		      }
+	   	      sprintf(state_file_str_mb,NOCATGETS("%s%s"),
+		       make_state->string_mb,NOCATGETS("/.make.state"));
+		      make_state = &state_filename;
+			/* adjust the length to reflect the appended string */
+		      make_state->hash.length += 12;
+		   }
+		} else { /* the file doesn't exist or no permission */
+		   char tmp_path[MAXPATHLEN];
+		   char *slashp;
+
+		   if (slashp = strrchr(make_state->string_mb, '/')) {
+		      strncpy(tmp_path, make_state->string_mb, 
+				(slashp - make_state->string_mb));
+			tmp_path[slashp - make_state->string_mb]=0;
+		      if(strlen(tmp_path)) {
+		        if(stat(tmp_path, &make_state_stat)) {
+			  warning(catgets(catd, 1, 192, "directory %s for .KEEP_STATE_FILE does not exist"),tmp_path);
+		        }
+		        if (access(tmp_path, F_OK) != 0) {
+			  warning(catgets(catd, 1, 193, "can't access dir %s"),tmp_path);
+		        }
+		      }
+		   }
+		}
+		if (report_dependencies_level != 1) {
+			Makefile_type	makefile_type_temp = makefile_type;
+			makefile_type = reading_statefile;
+			if (read_trace_level > 1) {
+				trace_reader = true;
+			}
+			(void) read_simple_file(make_state,
+						false,
+						false,
+						false,
+						false,
+						false,
+						true);
+			trace_reader = false;
+			makefile_type = makefile_type_temp;
+		}
+	}
+}
+
+/*
+ * Scan the argv for options and "=" type args and make them readonly.
+ */
+static void
+enter_argv_values(int argc, char *argv[], ASCII_Dyn_Array *makeflags_and_macro)
+{
+	register char		*cp;
+	register int		i;
+	int			length;
+	register Name		name;
+	int			opt_separator = argc; 
+	char			tmp_char;
+	wchar_t			*tmp_wcs_buffer;
+	register Name		value;
+	Boolean			append = false;
+	Property		macro;
+	struct stat		statbuf;
+
+
+	/* Read argv options and "=" type args and make them readonly. */
+	makefile_type = reading_nothing;
+	for (i = 1; i < argc; ++i) {
+		append = false;
+		if (argv[i] == NULL) {
+			continue;
+		} else if (((argv[i][0] == '-') && (argv[i][1] == '-')) ||
+			   ((argv[i][0] == (int) ' ') &&
+			    (argv[i][1] == (int) '-') &&
+			    (argv[i][2] == (int) ' ') &&
+			    (argv[i][3] == (int) '-'))) {
+			argv[i] = NULL;
+			opt_separator = i;
+			continue;
+		} else if ((i < opt_separator) && (argv[i][0] == (int) hyphen_char)) {
+			switch (parse_command_option(argv[i][1])) {
+			case 1:	/* -f seen */
+				++i;
+				continue;
+			case 2:	/* -c seen */
+				if (argv[i+1] == NULL) {
+					fatal(catgets(catd, 1, 194, "No dmake rcfile argument after -c flag"));
+				}
+				MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_RCFILE"));
+				name = GETNAME(wcs_buffer, FIND_LENGTH);
+				break;
+			case 4:	/* -g seen */
+				if (argv[i+1] == NULL) {
+					fatal(catgets(catd, 1, 195, "No dmake group argument after -g flag"));
+				}
+				MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_GROUP"));
+				name = GETNAME(wcs_buffer, FIND_LENGTH);
+				break;
+			case 8:	/* -j seen */
+				if (argv[i+1] == NULL) {
+					fatal(catgets(catd, 1, 196, "No dmake max jobs argument after -j flag"));
+				}
+				MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MAX_JOBS"));
+				name = GETNAME(wcs_buffer, FIND_LENGTH);
+				break;
+			case 16: /* -M seen */
+				if (argv[i+1] == NULL) {
+					fatal(catgets(catd, 1, 323, "No pmake machinesfile argument after -M flag"));
+				}
+				MBSTOWCS(wcs_buffer, NOCATGETS("PMAKE_MACHINESFILE"));
+				name = GETNAME(wcs_buffer, FIND_LENGTH);
+				break;
+			case 32: /* -m seen */
+				if (argv[i+1] == NULL) {
+					fatal(catgets(catd, 1, 197, "No dmake mode argument after -m flag"));
+				}
+				MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MODE"));
+				name = GETNAME(wcs_buffer, FIND_LENGTH);
+				break;
+			case 128: /* -O seen */
+				if (argv[i+1] == NULL) {
+					fatal(catgets(catd, 1, 287, "No file descriptor argument after -O flag"));
+				}
+				mtool_msgs_fd = atoi(argv[i+1]);
+				/* find out if mtool_msgs_fd is a valid file descriptor */
+				if (fstat(mtool_msgs_fd, &statbuf) < 0) {
+					fatal(catgets(catd, 1, 355, "Invalid file descriptor %d after -O flag"), mtool_msgs_fd);
+				}
+				argv[i] = NULL;
+				argv[i+1] = NULL;
+				continue;
+			case 256: /* -K seen */
+				if (argv[i+1] == NULL) {
+					fatal(catgets(catd, 1, 288, "No makestate filename argument after -K flag"));
+				}
+				MBSTOWCS(wcs_buffer, argv[i+1]);
+				make_state = GETNAME(wcs_buffer, FIND_LENGTH);
+				keep_state = true;
+				argv[i] = NULL;
+				argv[i+1] = NULL;
+				continue;
+			case 512:	/* -o seen */
+				if (argv[i+1] == NULL) {
+					fatal(catgets(catd, 1, 312, "No dmake output dir argument after -o flag"));
+				}
+				MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_ODIR"));
+				name = GETNAME(wcs_buffer, FIND_LENGTH);
+				break;
+			case 1024: /* -x seen */
+				if (argv[i+1] == NULL) {
+					fatal(catgets(catd, 1, 351, "No argument after -x flag"));
+				}
+				length = strlen( NOCATGETS("SUN_MAKE_COMPAT_MODE="));
+				if (strncmp(argv[i+1], NOCATGETS("SUN_MAKE_COMPAT_MODE="), length) == 0) {
+					argv[i+1] = &argv[i+1][length];
+					MBSTOWCS(wcs_buffer, NOCATGETS("SUN_MAKE_COMPAT_MODE"));
+					name = GETNAME(wcs_buffer, FIND_LENGTH);
+					dmake_compat_mode_specified = dmake_add_mode_specified;
+					break;
+				}
+				length = strlen( NOCATGETS("DMAKE_OUTPUT_MODE="));
+				if (strncmp(argv[i+1], NOCATGETS("DMAKE_OUTPUT_MODE="), length) == 0) {
+					argv[i+1] = &argv[i+1][length];
+					MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_OUTPUT_MODE"));
+					name = GETNAME(wcs_buffer, FIND_LENGTH);
+					dmake_output_mode_specified = dmake_add_mode_specified;
+				} else {
+					warning(catgets(catd, 1, 354, "Unknown argument `%s' after -x flag (ignored)"),
+					      argv[i+1]);
+					argv[i] = argv[i + 1] = NULL;
+					continue;
+				}
+				break;
+			default: /* Shouldn't reach here */
+				argv[i] = NULL;
+				continue;
+			}
+			argv[i] = NULL;
+			if (i == (argc - 1)) {
+				break;
+			}
+			if ((length = strlen(argv[i+1])) >= MAXPATHLEN) {
+				tmp_wcs_buffer = ALLOC_WC(length + 1);
+				(void) mbstowcs(tmp_wcs_buffer, argv[i+1], length + 1);
+				value = GETNAME(tmp_wcs_buffer, FIND_LENGTH);
+				retmem(tmp_wcs_buffer);
+			} else {
+				MBSTOWCS(wcs_buffer, argv[i+1]);
+				value = GETNAME(wcs_buffer, FIND_LENGTH);
+			}
+			argv[i+1] = NULL;
+		} else if ((cp = strchr(argv[i], (int) equal_char)) != NULL) {
+/* 
+ * Combine all macro in dynamic array
+ */
+			if(*(cp-1) == (int) plus_char)
+			{
+				if(isspace(*(cp-2))) {
+					append = true;
+					cp--;
+				}
+			}
+			if(!append)
+				append_or_replace_macro_in_dyn_array(makeflags_and_macro, argv[i]);
+
+			while (isspace(*(cp-1))) {
+				cp--;
+			}
+			tmp_char = *cp;
+			*cp = (int) nul_char;
+			MBSTOWCS(wcs_buffer, argv[i]);
+			*cp = tmp_char;
+			name = GETNAME(wcs_buffer, wslen(wcs_buffer));
+			while (*cp != (int) equal_char) {
+				cp++;
+			}
+			cp++;
+			while (isspace(*cp) && (*cp != (int) nul_char)) {
+				cp++;
+			}
+			if ((length = strlen(cp)) >= MAXPATHLEN) {
+				tmp_wcs_buffer = ALLOC_WC(length + 1);
+				(void) mbstowcs(tmp_wcs_buffer, cp, length + 1);
+				value = GETNAME(tmp_wcs_buffer, FIND_LENGTH);
+				retmem(tmp_wcs_buffer);
+			} else {
+				MBSTOWCS(wcs_buffer, cp);
+				value = GETNAME(wcs_buffer, FIND_LENGTH);
+			}
+			argv[i] = NULL;
+		} else {
+			/* Illegal MAKEFLAGS argument */
+			continue;
+		}
+		if(append) {
+			setvar_append(name, value);
+			append = false;
+		} else {
+			macro = maybe_append_prop(name, macro_prop);
+			macro->body.macro.exported = true;
+			SETVAR(name, value, false)->body.macro.read_only = true;
+		}
+	}
+}
+
+/*
+ * Append the DMake option and value to the MAKEFLAGS string.
+ */
+static void
+append_makeflags_string(Name name, register String makeflags_string)
+{
+	char		*option;
+
+	if (strcmp(name->string_mb, NOCATGETS("DMAKE_GROUP")) == 0) {
+		option = NOCATGETS(" -g ");
+	} else if (strcmp(name->string_mb, NOCATGETS("DMAKE_MAX_JOBS")) == 0) {
+		option = NOCATGETS(" -j ");
+	} else if (strcmp(name->string_mb, NOCATGETS("DMAKE_MODE")) == 0) {
+		option = NOCATGETS(" -m ");
+	} else if (strcmp(name->string_mb, NOCATGETS("DMAKE_ODIR")) == 0) {
+		option = NOCATGETS(" -o ");
+	} else if (strcmp(name->string_mb, NOCATGETS("DMAKE_RCFILE")) == 0) {
+		option = NOCATGETS(" -c ");
+	} else if (strcmp(name->string_mb, NOCATGETS("PMAKE_MACHINESFILE")) == 0) {
+		option = NOCATGETS(" -M ");
+	} else if (strcmp(name->string_mb, NOCATGETS("DMAKE_OUTPUT_MODE")) == 0) {
+		option = NOCATGETS(" -x DMAKE_OUTPUT_MODE=");
+	} else if (strcmp(name->string_mb, NOCATGETS("SUN_MAKE_COMPAT_MODE")) == 0) {
+		option = NOCATGETS(" -x SUN_MAKE_COMPAT_MODE=");
+	} else {
+		fatal(catgets(catd, 1, 289, "Internal error: name not recognized in append_makeflags_string()"));
+	}
+	Property prop = maybe_append_prop(name, macro_prop);
+	if( prop == 0 || prop->body.macro.value == 0 ||
+	    prop->body.macro.value->string_mb == 0 ) {
+		return;
+	}
+	char mbs_value[MAXPATHLEN + 100];
+	strcpy(mbs_value, option);
+	strcat(mbs_value, prop->body.macro.value->string_mb);
+	MBSTOWCS(wcs_buffer, mbs_value);
+	append_string(wcs_buffer, makeflags_string, FIND_LENGTH);
+}
+
+/*
+ *	read_environment(read_only)
+ *
+ *	This routine reads the process environment when make starts and enters
+ *	it as make macros. The environment variable SHELL is ignored.
+ *
+ *	Parameters:
+ *		read_only	Should we make env vars read only?
+ *
+ *	Global variables used:
+ *		report_pwd	Set if this make was started by other make
+ */
+static void
+read_environment(Boolean read_only)
+{
+	register char		**environment;
+	int			length;
+	wchar_t			*tmp_wcs_buffer;
+	Boolean			alloced_tmp_wcs_buffer = false;
+	register wchar_t	*name;
+	register wchar_t	*value;
+	register Name		macro;
+	Property		val;
+	Boolean			read_only_saved;
+
+	reading_environment = true;
+	environment = environ;
+	for (; *environment; environment++) {
+		read_only_saved = read_only;
+		if ((length = strlen(*environment)) >= MAXPATHLEN) {
+			tmp_wcs_buffer = ALLOC_WC(length + 1);
+			alloced_tmp_wcs_buffer = true;
+			(void) mbstowcs(tmp_wcs_buffer, *environment, length + 1);
+			name = tmp_wcs_buffer;
+		} else {
+			MBSTOWCS(wcs_buffer, *environment);
+			name = wcs_buffer;
+		}
+		value = (wchar_t *) wschr(name, (int) equal_char);
+
+		/*
+		 * Looks like there's a bug in the system, but sometimes
+		 * you can get blank lines in *environment.
+		 */
+		if (!value) {
+			continue;
+		}
+		MBSTOWCS(wcs_buffer2, NOCATGETS("SHELL="));
+		if (IS_WEQUALN(name, wcs_buffer2, wslen(wcs_buffer2))) {
+			continue;
+		}
+		MBSTOWCS(wcs_buffer2, NOCATGETS("MAKEFLAGS="));
+		if (IS_WEQUALN(name, wcs_buffer2, wslen(wcs_buffer2))) {
+			report_pwd = true;
+			/*
+			 * In POSIX mode we do not want MAKEFLAGS to be readonly.
+			 * If the MAKEFLAGS macro is subsequently set by the makefile,
+			 * it replaces the MAKEFLAGS variable currently found in the
+			 * environment.
+			 * See Assertion 50 in section 6.2.5.3 of standard P1003.3.2/D8.
+			 */
+			if(posix) {
+				read_only_saved = false;
+			}
+		}
+
+		/*
+		 * We ignore SUNPRO_DEPENDENCIES and NSE_DEP. Those
+		 * environment variables are set by make and read by 
+		 * cpp which then writes info to .make.dependency.xxx and 
+		 * .nse_depinfo. When make is invoked by another make 
+		 * (recursive make), we don't want to read this because 
+		 * then the child make will end up writing to the parent 
+		 * directory's .make.state and .nse_depinfo and clobbering
+		 * them. 
+		 */
+		MBSTOWCS(wcs_buffer2, NOCATGETS("SUNPRO_DEPENDENCIES"));
+		if (IS_WEQUALN(name, wcs_buffer2, wslen(wcs_buffer2))) {
+			continue;
+		}
+#ifdef NSE
+		MBSTOWCS(wcs_buffer2, NOCATGETS("NSE_DEP"));
+		if (IS_WEQUALN(name, wcs_buffer2, wslen(wcs_buffer2))) {
+			continue;
+		}
+#endif
+
+		macro = GETNAME(name, value - name);
+		maybe_append_prop(macro, macro_prop)->body.macro.exported =
+		  true;
+		if ((value == NULL) || ((value + 1)[0] == (int) nul_char)) {
+			val = setvar_daemon(macro,
+					    (Name) NULL,
+					    false, no_daemon, false, debug_level);
+		} else {
+			val = setvar_daemon(macro,
+					    GETNAME(value + 1, FIND_LENGTH),
+					    false, no_daemon, false, debug_level);
+		}
+#ifdef NSE
+                /*
+	         * Must be after the call to setvar() as it sets
+	         * imported to false.
+	         */
+		maybe_append_prop(macro, macro_prop)->body.macro.imported = true;
+#endif
+		val->body.macro.read_only = read_only_saved;
+		if (alloced_tmp_wcs_buffer) {
+			retmem(tmp_wcs_buffer);
+			alloced_tmp_wcs_buffer = false;
+		}
+	}
+	reading_environment = false;
+}
+
+/*
+ *	read_makefile(makefile, complain, must_exist, report_file)
+ *
+ *	Read one makefile and check the result
+ *
+ *	Return value:
+ *				false is the read failed
+ *
+ *	Parameters:
+ *		makefile	The file to read
+ *		complain	Passed thru to read_simple_file()
+ *		must_exist	Passed thru to read_simple_file()
+ *		report_file	Passed thru to read_simple_file()
+ *
+ *	Global variables used:
+ *		makefile_type	Set to indicate we are reading main file
+ *		recursion_level	Initialized
+ */
+static Boolean
+read_makefile(register Name makefile, Boolean complain, Boolean must_exist, Boolean report_file)
+{
+	Boolean			b;
+	
+	makefile_type = reading_makefile;
+	recursion_level = 0;
+#ifdef NSE
+	wscpy(current_makefile, makefile->string);
+#endif
+	reading_dependencies = true;
+	b = read_simple_file(makefile, true, true, complain,
+			     must_exist, report_file, false);
+	reading_dependencies = false;
+	return b;
+}
+
+/*
+ *	make_targets(argc, argv, parallel_flag)
+ *
+ *	Call doname on the specified targets
+ *
+ *	Parameters:
+ *		argc		You know what this is
+ *		argv		You know what this is
+ *		parallel_flag	True if building in parallel
+ *
+ *	Global variables used:
+ *		build_failed_seen Used to generated message after failed -k
+ *		commands_done	Used to generate message "Up to date"
+ *		default_target_to_build	First proper target in makefile
+ *		init		The Name ".INIT", use to run command
+ *		parallel	Global parallel building flag
+ *		quest		make -q, suppresses messages
+ *		recursion_level	Initialized, used for tracing
+ *		report_dependencies make -P, regroves whole process
+ */
+static void
+make_targets(int argc, char **argv, Boolean parallel_flag)
+{
+	int			i;
+	char			*cp;
+	Doname			result;
+	register Boolean	target_to_make_found = false;
+
+	(void) doname(init, true, true);
+	recursion_level = 1;
+	parallel = parallel_flag;
+/*
+ *	make remaining args
+ */
+#ifdef TEAMWARE_MAKE_CMN
+/*
+	if ((report_dependencies_level == 0) && parallel) {
+ */
+	if (parallel) {
+		/*
+		 * If building targets in parallel, start all of the
+		 * remaining args to build in parallel.
+		 */
+		for (i = 1; i < argc; i++) {
+			if ((cp = argv[i]) != NULL) {
+				commands_done = false;
+				if ((cp[0] == (int) period_char) &&
+				    (cp[1] == (int) slash_char)) {
+					cp += 2;
+				}
+				 if((cp[0] == (int) ' ') &&
+				    (cp[1] == (int) '-') &&
+				    (cp[2] == (int) ' ') &&
+				    (cp[3] == (int) '-')) {
+			            argv[i] = NULL;
+					continue;
+				}
+				MBSTOWCS(wcs_buffer, cp);
+				//default_target_to_build = GETNAME(wcs_buffer,
+				//				  FIND_LENGTH);
+				default_target_to_build = normalize_name(wcs_buffer,
+								  wslen(wcs_buffer));
+				if (default_target_to_build == wait_name) {
+					if (parallel_process_cnt > 0) {
+						finish_running();
+					}
+					continue;
+				}
+				top_level_target = get_wstring(default_target_to_build->string_mb);
+				/*
+				 * If we can't execute the current target in
+				 * parallel, hold off the target processing
+				 * to preserve the order of the targets as they appeared
+				 * in command line.
+				 */
+				if (!parallel_ok(default_target_to_build, false)
+						&& parallel_process_cnt > 0) {
+					finish_running();
+				}
+				result = doname_check(default_target_to_build,
+						      true,
+						      false,
+						      false);
+				gather_recursive_deps();
+				if (/* !commands_done && */
+				    (result == build_ok) &&
+				    !quest &&
+				    (report_dependencies_level == 0) /*  &&
+				    (exists(default_target_to_build) > file_doesnt_exist)  */) {
+					if (posix) {
+						if (!commands_done) {
+							(void) printf(catgets(catd, 1, 293, "`%s' is updated.\n"),
+						 		      default_target_to_build->string_mb);
+						} else {
+							if (no_action_was_taken) {
+								(void) printf(catgets(catd, 1, 294, "`%s': no action was taken.\n"),
+						 			      default_target_to_build->string_mb);
+							}
+						}
+					} else {
+						default_target_to_build->stat.time = file_no_time;
+						if (!commands_done &&
+						    (exists(default_target_to_build) > file_doesnt_exist)) {
+							(void) printf(catgets(catd, 1, 295, "`%s' is up to date.\n"),
+								      default_target_to_build->string_mb);
+						}
+					}
+				}
+			}
+		}
+		/* Now wait for all of the targets to finish running */
+		finish_running();
+		//		setjmp(jmpbuffer);
+		
+	}
+#endif
+	for (i = 1; i < argc; i++) {
+		if ((cp = argv[i]) != NULL) {
+			target_to_make_found = true;
+			if ((cp[0] == (int) period_char) &&
+			    (cp[1] == (int) slash_char)) {
+				cp += 2;
+			}
+				 if((cp[0] == (int) ' ') &&
+				    (cp[1] == (int) '-') &&
+				    (cp[2] == (int) ' ') &&
+				    (cp[3] == (int) '-')) {
+			            argv[i] = NULL;
+					continue;
+				}
+			MBSTOWCS(wcs_buffer, cp);
+			default_target_to_build = normalize_name(wcs_buffer, wslen(wcs_buffer));
+			top_level_target = get_wstring(default_target_to_build->string_mb);
+			report_recursion(default_target_to_build);
+			commands_done = false;
+			if (parallel) {
+				result = (Doname) default_target_to_build->state;
+			} else {
+				result = doname_check(default_target_to_build,
+						      true,
+						      false,
+						      false);
+			}
+			gather_recursive_deps();
+			if (build_failed_seen) {
+				build_failed_ever_seen = true;
+				warning(catgets(catd, 1, 200, "Target `%s' not remade because of errors"),
+					default_target_to_build->string_mb);
+			}
+			build_failed_seen = false;
+			if (report_dependencies_level > 0) {
+				print_dependencies(default_target_to_build,
+						   get_prop(default_target_to_build->prop,
+							    line_prop));
+			}
+			default_target_to_build->stat.time =
+			  file_no_time;
+			if (default_target_to_build->colon_splits > 0) {
+				default_target_to_build->state =
+				  build_dont_know;
+			}
+			if (!parallel &&
+			    /* !commands_done && */
+			    (result == build_ok) &&
+			    !quest &&
+			    (report_dependencies_level == 0) /*  &&
+			    (exists(default_target_to_build) > file_doesnt_exist)  */) {
+				if (posix) {
+					if (!commands_done) {
+						(void) printf(catgets(catd, 1, 296, "`%s' is updated.\n"),
+					 		      default_target_to_build->string_mb);
+					} else {
+						if (no_action_was_taken) {
+							(void) printf(catgets(catd, 1, 297, "`%s': no action was taken.\n"),
+					 			      default_target_to_build->string_mb);
+						}
+					}
+				} else {
+					if (!commands_done &&
+					    (exists(default_target_to_build) > file_doesnt_exist)) {
+						(void) printf(catgets(catd, 1, 298, "`%s' is up to date.\n"),
+							      default_target_to_build->string_mb);
+					}
+				}
+			}
+		}
+	}
+
+/*
+ *	If no file arguments have been encountered,
+ *	make the first name encountered that doesnt start with a dot
+ */
+	if (!target_to_make_found) {
+		if (default_target_to_build == NULL) {
+			fatal(catgets(catd, 1, 202, "No arguments to build"));
+		}
+		commands_done = false;
+		top_level_target = get_wstring(default_target_to_build->string_mb);
+		report_recursion(default_target_to_build);
+
+
+		if (getenv(NOCATGETS("SPRO_EXPAND_ERRORS"))){
+			(void) printf(NOCATGETS("::(%s)\n"),
+				      default_target_to_build->string_mb);
+		}
+
+
+#ifdef TEAMWARE_MAKE_CMN
+		result = doname_parallel(default_target_to_build, true, false);
+#else
+		result = doname_check(default_target_to_build, true,
+				      false, false);
+#endif
+		gather_recursive_deps();
+		if (build_failed_seen) {
+			build_failed_ever_seen = true;
+			warning(catgets(catd, 1, 203, "Target `%s' not remade because of errors"),
+				default_target_to_build->string_mb);
+		}
+		build_failed_seen = false;
+		if (report_dependencies_level > 0) {
+			print_dependencies(default_target_to_build,
+					   get_prop(default_target_to_build->
+						    prop,
+						    line_prop));
+		}
+		default_target_to_build->stat.time = file_no_time;
+		if (default_target_to_build->colon_splits > 0) {
+			default_target_to_build->state = build_dont_know;
+		}
+		if (/* !commands_done && */
+		    (result == build_ok) &&
+		    !quest &&
+		    (report_dependencies_level == 0) /*  &&
+		    (exists(default_target_to_build) > file_doesnt_exist)  */) {
+			if (posix) {
+				if (!commands_done) {
+					(void) printf(catgets(catd, 1, 299, "`%s' is updated.\n"),
+				 		      default_target_to_build->string_mb);
+				} else {
+					if (no_action_was_taken) {
+						(void) printf(catgets(catd, 1, 300, "`%s': no action was taken.\n"),
+							      default_target_to_build->string_mb);
+					}
+				}
+			} else {
+				if (!commands_done &&
+				    (exists(default_target_to_build) > file_doesnt_exist)) {
+					(void) printf(catgets(catd, 1, 301, "`%s' is up to date.\n"),
+						      default_target_to_build->string_mb);
+				}
+			}
+		}
+	}
+}
+
+/*
+ *	report_recursion(target)
+ *
+ *	If this is a recursive make and the parent make has KEEP_STATE on
+ *	this routine reports the dependency to the parent make
+ *
+ *	Parameters:
+ *		target		Target to report
+ *
+ *	Global variables used:
+ *		makefiles_used		List of makefiles read
+ *		recursive_name		The Name ".RECURSIVE", printed
+ *		report_dependency	dwight
+ */
+static void
+report_recursion(register Name target)
+{
+	register FILE		*report_file = get_report_file();
+
+	if ((report_file == NULL) || (report_file == (FILE*)-1)) {
+		return;
+	}
+	if (primary_makefile == NULL) {
+		/*
+		 * This can happen when there is no makefile and
+		 * only implicit rules are being used.
+		 */
+#ifdef NSE
+		nse_no_makefile(target);
+#endif
+		return;
+	}
+	(void) fprintf(report_file,
+		       "%s: %s ",
+		       get_target_being_reported_for(),
+		       recursive_name->string_mb);
+	report_dependency(get_current_path());
+	report_dependency(target->string_mb);
+	report_dependency(primary_makefile->string_mb);
+	(void) fprintf(report_file, "\n");
+}
+
+/* Next function "append_or_replace_macro_in_dyn_array" must be in "misc.cc". */
+/* NIKMOL */
+extern void
+append_or_replace_macro_in_dyn_array(ASCII_Dyn_Array *Ar, char *macro)
+{
+	register char	*cp0;	/* work pointer in macro */
+	register char	*cp1;	/* work pointer in array */
+	register char	*cp2;	/* work pointer in array */
+	register char	*cp3;	/* work pointer in array */
+	register char	*name;	/* macro name */
+	register char	*value;	/* macro value */
+	register int 	len_array;
+	register int 	len_macro;
+
+	char * esc_value = NULL;
+	int esc_len;
+
+	if (!(len_macro = strlen(macro))) return;
+	name = macro;
+	while (isspace(*(name))) {
+		name++;
+	}
+	if (!(value = strchr(name, (int) equal_char))) {
+		/* no '=' in macro */
+		goto ERROR_MACRO;
+	}
+	cp0 = value;
+	value++;
+	while (isspace(*(value))) {
+		value++;
+	}
+	while (isspace(*(cp0-1))) {
+		cp0--;
+	}
+	if (cp0 <= name) goto ERROR_MACRO; /* no name */
+	if (!(Ar->size)) goto ALLOC_ARRAY;
+	cp1 = Ar->start;
+
+LOOK_FOR_NAME:
+	if (!(cp1 = strchr(cp1, name[0]))) goto APPEND_MACRO;
+	if (!(cp2 = strchr(cp1, (int) equal_char))) goto APPEND_MACRO;
+	if (strncmp(cp1, name, (size_t)(cp0-name))) {
+		/* another name */
+		cp1++;
+		goto LOOK_FOR_NAME;
+	}
+	if (cp1 != Ar->start) {
+		if (!isspace(*(cp1-1))) {
+			/* another name */
+			cp1++;
+			goto LOOK_FOR_NAME;
+		}
+	}
+	for (cp3 = cp1 + (cp0-name); cp3 < cp2; cp3++) {
+		if (isspace(*cp3)) continue;
+		/* else: another name */
+		cp1++;
+		goto LOOK_FOR_NAME;
+	}
+	/* Look for the next macro name in array */
+	cp3 = cp2+1;
+	if (*cp3 != (int) doublequote_char) {
+		/* internal error */
+		goto ERROR_MACRO;
+	}
+	if (!(cp3 = strchr(cp3+1, (int) doublequote_char))) {
+		/* internal error */
+		goto ERROR_MACRO;
+	}
+	cp3++;
+	while (isspace(*cp3)) {
+		cp3++;
+	}
+	
+	cp2 = cp1;  /* remove old macro */
+	if ((*cp3) && (cp3 < Ar->start + Ar->size)) {
+		for (; cp3 < Ar->start + Ar->size; cp3++) {
+			*cp2++ = *cp3;
+		}
+	} 
+	for (; cp2 < Ar->start + Ar->size; cp2++) {
+		*cp2 = 0;
+	}
+	if (*cp1) {
+		/* check next name */
+		goto LOOK_FOR_NAME;
+	}
+	goto APPEND_MACRO;
+
+ALLOC_ARRAY:
+	if (Ar->size) {
+		cp1 = Ar->start;
+	} else {
+		cp1 = 0;
+	}
+	Ar->size += 128;
+	Ar->start = getmem(Ar->size);
+	for (len_array=0; len_array < Ar->size; len_array++) {
+		Ar->start[len_array] = 0;
+	}
+	if (cp1) {
+		strcpy(Ar->start, cp1);
+		retmem((wchar_t *) cp1);
+	}
+
+APPEND_MACRO:
+	len_array = strlen(Ar->start);
+	esc_value = (char*)malloc(strlen(value)*2 + 1);
+	quote_str(value, esc_value);
+	esc_len = strlen(esc_value) - strlen(value);
+	if (len_array + len_macro + esc_len + 5 >= Ar->size) goto  ALLOC_ARRAY;
+	strcat(Ar->start, " ");
+	strncat(Ar->start, name, cp0-name);
+	strcat(Ar->start, "=");
+	strncat(Ar->start, esc_value, strlen(esc_value));
+	free(esc_value);
+	return;
+ERROR_MACRO:	
+	/* Macro without '=' or with invalid left/right part */
+	return;
+}
+
+#ifdef TEAMWARE_MAKE_CMN
+/*
+ * This function, if registered w/ avo_cli_get_license(), will be called
+ * if the application is about to exit because:
+ *   1) there has been certain unrecoverable error(s) that cause the
+ *      application to exit immediately.
+ *   2) the user has lost a license while the application is running.
+ */
+extern "C" void
+dmake_exit_callback(void)
+{
+	fatal(catgets(catd, 1, 306, "can not get a license, exiting..."));
+	exit(1);
+}
+
+/*
+ * This function, if registered w/ avo_cli_get_license(), will be called
+ * if the application can not get a license.
+ */
+extern "C" void
+dmake_message_callback(char *err_msg)
+{
+	static Boolean	first = true;
+
+	if (!first) {
+		return;
+	}
+	first = false;
+	if ((!list_all_targets) &&
+	    (report_dependencies_level == 0) &&
+	    (dmake_mode_type != serial_mode)) {
+		warning(catgets(catd, 1, 313, "can not get a TeamWare license, defaulting to serial mode..."));
+	}
+}
+#endif
+
+#ifdef DISTRIBUTED
+/*
+ * Returns whether -c is set or not.
+ */
+Boolean
+get_dmake_rcfile_specified(void)
+{
+	return(dmake_rcfile_specified);
+}
+
+/*
+ * Returns whether -g is set or not.
+ */
+Boolean
+get_dmake_group_specified(void)
+{
+	return(dmake_group_specified);
+}
+
+/*
+ * Returns whether -j is set or not.
+ */
+Boolean
+get_dmake_max_jobs_specified(void)
+{
+	return(dmake_max_jobs_specified);
+}
+
+/*
+ * Returns whether -m is set or not.
+ */
+Boolean
+get_dmake_mode_specified(void)
+{
+	return(dmake_mode_specified);
+}
+
+/*
+ * Returns whether -o is set or not.
+ */
+Boolean
+get_dmake_odir_specified(void)
+{
+	return(dmake_odir_specified);
+}
+
+#endif
+
+static void
+report_dir_enter_leave(Boolean entering)
+{
+	char	rcwd[MAXPATHLEN];
+static	char *	mlev = NULL;
+	char *	make_level_str = NULL;
+	int	make_level_val = 0;
+
+	make_level_str = getenv(NOCATGETS("MAKELEVEL"));
+	if(make_level_str) {
+		make_level_val = atoi(make_level_str);
+	}
+	if(mlev == NULL) {
+		mlev = (char*) malloc(MAXPATHLEN);
+	}
+	if(entering) {
+		sprintf(mlev, NOCATGETS("MAKELEVEL=%d"), make_level_val + 1);
+	} else {
+		make_level_val--;
+		sprintf(mlev, NOCATGETS("MAKELEVEL=%d"), make_level_val);
+	}
+	putenv(mlev);
+
+	if(report_cwd) {
+		if(make_level_val <= 0) {
+			if(entering) {
+#ifdef TEAMWARE_MAKE_CMN
+				sprintf( rcwd
+				       , catgets(catd, 1, 329, "dmake: Entering directory `%s'\n")
+				       , get_current_path());
+#else
+				sprintf( rcwd
+				       , catgets(catd, 1, 330, "make: Entering directory `%s'\n")
+				       , get_current_path());
+#endif
+			} else {
+#ifdef TEAMWARE_MAKE_CMN
+				sprintf( rcwd
+				       , catgets(catd, 1, 331, "dmake: Leaving directory `%s'\n")
+				       , get_current_path());
+#else
+				sprintf( rcwd
+				       , catgets(catd, 1, 332, "make: Leaving directory `%s'\n")
+				       , get_current_path());
+#endif
+			}
+		} else {
+			if(entering) {
+#ifdef TEAMWARE_MAKE_CMN
+				sprintf( rcwd
+				       , catgets(catd, 1, 333, "dmake[%d]: Entering directory `%s'\n")
+				       , make_level_val, get_current_path());
+#else
+				sprintf( rcwd
+				       , catgets(catd, 1, 334, "make[%d]: Entering directory `%s'\n")
+				       , make_level_val, get_current_path());
+#endif
+			} else {
+#ifdef TEAMWARE_MAKE_CMN
+				sprintf( rcwd
+				       , catgets(catd, 1, 335, "dmake[%d]: Leaving directory `%s'\n")
+				       , make_level_val, get_current_path());
+#else
+				sprintf( rcwd
+				       , catgets(catd, 1, 336, "make[%d]: Leaving directory `%s'\n")
+				       , make_level_val, get_current_path());
+#endif
+			}
+		}
+		printf(NOCATGETS("%s"), rcwd);
+	}
+}
--- /dev/null	2015-05-20 11:04:09.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/common/make.cc	2015-05-20 11:04:09.390580621 -0400
@@ -0,0 +1,29 @@
+/*
+ * 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 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)make.cc 1.2 06/12/12
+ */
+
+#pragma	ident	"@(#)make.cc	1.2	06/12/12"
--- /dev/null	2015-05-20 11:04:09.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/common/make.rules.file	2015-05-20 11:04:09.578010594 -0400
@@ -0,0 +1,500 @@
+#
+# 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 2003 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)make.rules.file 1.22 06/12/12
+#
+
+SUFFIXES = .o .c .c~ .cc .cc~ .y .y~ .l .l~ .s .s~ .sh .sh~ .S .S~ .i .ln \
+	.h .h~ .f .f~ .for .for~ .F .F~ .f90 .f90~ .ftn .ftn~ .mod .mod~ \
+	.sym .def .def~ .p .p~ .r .r~ .cps .cps~ .C .C~ .Y .Y~ .L .L~ \
+	.java .java~ .class
+
+.SUFFIXES: $(SUFFIXES)
+
+# OUTPUT_OPTION should be defined to "-o $@" when
+# the default rules are used for non-local files.
+OUTPUT_OPTION=
+
+#	C language section.
+CC=cc
+CFLAGS=
+CPPFLAGS=
+LINT=lint
+LINTFLAGS=
+COMPILE.c=$(CC) $(CFLAGS) $(CPPFLAGS) -c
+LINK.c=$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) 
+LINT.c=$(LINT) $(LINTFLAGS) $(CPPFLAGS) 
+.c:
+	$(LINK.c) -o $@ $< $(LDLIBS)
+.c~:
+	$(GET) $(GFLAGS) -p $< > $*.c
+	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $*.c
+.c.o:
+	$(COMPILE.c) $(OUTPUT_OPTION) $<
+.c~.o:
+	$(GET) $(GFLAGS) -p $< > $*.c
+	$(CC) $(CFLAGS) -c  $*.c
+.c.i:
+	$(CC) $(CFLAGS) $(CPPFLAGS) -P $<
+.c~.i:
+	$(GET) $(GFLAGS) -p $< > $*.c
+	$(CC) $(CFLAGS) $(CPPFLAGS) -P $*.c
+.c.ln:
+	$(LINT.c) $(OUTPUT_OPTION) -c $<
+.c~.ln:
+	$(GET) $(GFLAGS) -p $< > $*.c
+	$(LINT.c) $(OUTPUT_OPTION) -c $*.c
+.c.a:
+	$(COMPILE.c) -o $% $<
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+.c~.a:
+	$(GET) $(GFLAGS) -p $< > $*.c
+	$(COMPILE.c) -o $% $*.c
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+
+#	C language section. yacc.
+YACC=yacc
+YFLAGS=
+YACC.y=$(YACC) $(YFLAGS)
+.y:
+	$(YACC.y) $<
+	$(LINK.c) -o $@ y.tab.c $(LDLIBS)
+	$(RM) y.tab.c
+.y~:
+	$(GET) $(GFLAGS) -p $< > $*.y
+	$(YACC) $(YFLAGS) $*.y
+	$(COMPILE.c) -o $@ y.tab.c
+	$(RM) y.tab.c
+
+.y.c:
+	$(YACC.y) $<
+	mv y.tab.c $@
+.y~.c:
+	$(GET) $(GFLAGS) -p $< > $*.y
+	$(YACC) $(YFLAGS) $*.y
+	mv y.tab.c $@
+.y.ln:
+	$(YACC.y) $<
+	$(LINT.c) -o $@ -i y.tab.c
+	$(RM) y.tab.c
+.y~.ln:
+	$(GET) $(GFLAGS) -p $< > $*.y
+	$(YACC.y) $*.y
+	$(LINT.c) -o $@ -i y.tab.c
+	$(RM) y.tab.c
+.y.o:
+	$(YACC.y) $<
+	$(COMPILE.c) -o $@ y.tab.c
+	$(RM) y.tab.c
+.y~.o:
+	$(GET) $(GFLAGS) -p $< > $*.y
+	$(YACC) $(YFLAGS) $*.y
+	$(CC) $(CFLAGS) -c y.tab.c
+	rm -f y.tab.c
+	mv y.tab.o $@
+
+#	C language section. lex.
+LEX=lex
+LFLAGS=
+LEX.l=$(LEX) $(LFLAGS) -t
+.l:
+	$(RM) $*.c
+	$(LEX.l) $< > $*.c
+	$(LINK.c) -o $@ $*.c -ll $(LDLIBS)
+	$(RM) $*.c
+.l~:
+	$(GET) $(GFLAGS) -p $< > $*.l
+	$(LEX) $(LFLAGS) $*.l
+	$(CC) $(CFLAGS) -c lex.yy.c
+	rm -f lex.yy.c
+	mv lex.yy.c $@
+
+.l.c :
+	$(RM) $@
+	$(LEX.l) $< > $@
+.l~.c:
+	$(GET) $(GFLAGS) -p $< > $*.l
+	$(LEX) $(LFLAGS) $*.l
+	mv lex.yy.c $@
+.l.ln:
+	$(RM) $*.c
+	$(LEX.l) $< > $*.c
+	$(LINT.c) -o $@ -i $*.c
+	$(RM) $*.c
+.l~.ln:
+	$(GET) $(GFLAGS) -p $< > $*.l
+	$(RM) $*.c
+	$(LEX.l) $*.l > $*.c
+	$(LINT.c) -o $@ -i $*.c
+	$(RM) $*.c
+.l.o:
+	$(RM) $*.c
+	$(LEX.l) $< > $*.c
+	$(COMPILE.c) -o $@ $*.c
+	$(RM) $*.c
+.l~.o:
+	$(GET) $(GFLAGS) -p $< > $*.l
+	$(LEX) $(LFLAGS) $*.l
+	$(CC) $(CFLAGS) -c lex.yy.c
+	rm -f lex.yy.c
+	mv lex.yy.c $@
+
+#       C++ language section.
+CCC=CC
+CCFLAGS=
+COMPILE.cc=$(CCC) $(CCFLAGS) $(CPPFLAGS)  -c
+LINK.cc=$(CCC) $(CCFLAGS) $(CPPFLAGS) $(LDFLAGS) 
+COMPILE.C=$(CCC) $(CCFLAGS) $(CPPFLAGS)  -c
+LINK.C=$(CCC) $(CCFLAGS) $(CPPFLAGS) $(LDFLAGS) 
+.cc:
+	$(LINK.cc) -o $@ $< $(LDLIBS)
+.cc~:
+	$(GET) $(GFLAGS) -p $< > $*.cc
+	$(LINK.cc) -o $@ $*.cc $(LDLIBS)
+.cc.o:
+	$(COMPILE.cc) $(OUTPUT_OPTION) $<
+.cc~.o:
+	$(GET) $(GFLAGS) -p $< > $*.cc
+	$(COMPILE.cc) $(OUTPUT_OPTION) $*.cc
+.cc.i:
+	$(CCC) $(CCFLAGS) $(CPPFLAGS) -P $<
+.cc~.i:
+	$(GET) $(GFLAGS) -p $< > $*.cc
+	$(CCC) $(CCFLAGS) $(CPPFLAGS) -P $*.cc
+.cc.a:
+	$(COMPILE.cc) -o $% $<
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+.cc~.a:
+	$(GET) $(GFLAGS) -p $< > $*.cc
+	$(COMPILE.cc) -o $% $*.cc
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+
+.C:
+	$(LINK.C) -o $@ $< $(LDLIBS)
+.C~:
+	$(GET) $(GFLAGS) -p $< > $*.C
+	$(LINK.C) -o $@ $*.C $(LDLIBS)
+.C.o:
+	$(COMPILE.C) $(OUTPUT_OPTION) $<
+.C~.o:
+	$(GET) $(GFLAGS) -p $< > $*.C
+	$(COMPILE.C) $(OUTPUT_OPTION) $*.C
+.C.i:
+	$(CCC) $(CCFLAGS) $(CPPFLAGS) -P $<
+.C~.i:
+	$(GET) $(GFLAGS) -p $< > $*.C
+	$(CCC) $(CCFLAGS) $(CPPFLAGS) -P  $*.C
+.C.a:
+	$(COMPILE.C) -o $% $<
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+.C~.a:
+	$(GET) $(GFLAGS) -p $< > $*.C
+	$(COMPILE.C) -o $% $*.C
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+
+#	FORTRAN section.
+FC=f77
+FFLAGS=
+COMPILE.f=$(FC) $(FFLAGS)  -c
+LINK.f=$(FC) $(FFLAGS) $(LDFLAGS) 
+COMPILE.F=$(FC) $(FFLAGS) $(CPPFLAGS)  -c
+LINK.F=$(FC) $(FFLAGS) $(CPPFLAGS) $(LDFLAGS) 
+.f:
+	$(LINK.f) -o $@ $< $(LDLIBS)
+.f~:
+	$(GET) $(GFLAGS) -p $< > $*.f
+	$(FC) $(FFLAGS) $(LDFLAGS) -o $@ $*.f
+.f.o:
+	$(COMPILE.f) $(OUTPUT_OPTION) $<
+.f~.o:
+	$(GET) $(GFLAGS) -p $< > $*.f
+	$(FC) $(FFLAGS) -c  $*.f
+.f.a:
+	$(COMPILE.f) -o $% $<
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+.f~.a:
+	$(GET) $(GFLAGS) -p $< > $*.f
+	$(COMPILE.f) -o $% $*.f
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+.for:
+	$(LINK.f) -o $@ $< $(LDLIBS)
+.for~:
+	$(GET) $(GFLAGS) -p $< > $*.for
+	$(FC) $(FFLAGS) $(LDFLAGS) -o $@ $*.for
+.for.o:
+	$(COMPILE.f) $(OUTPUT_OPTION) $<
+.for~.o:
+	$(GET) $(GFLAGS) -p $< > $*.for
+	$(FC) $(FFLAGS) -c  $*.for
+.for.a:
+	$(COMPILE.f) -o $% $<
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+.for~.a:
+	$(GET) $(GFLAGS) -p $< > $*.for
+	$(COMPILE.f) -o $% $*.for
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+.F:
+	$(LINK.F) -o $@ $< $(LDLIBS)
+.F~:
+	$(GET) $(GFLAGS) -p $< > $*.F
+	$(FC) $(FFLAGS) $(LDFLAGS) -o $@ $*.F
+.F.o:
+	$(COMPILE.F) $(OUTPUT_OPTION) $<
+.F~.o:
+	$(GET) $(GFLAGS) -p $< > $*.F
+	$(FC) $(FFLAGS) -c  $*.F
+.F.a:
+	$(COMPILE.F) -o $% $<
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+.F~.a:
+	$(GET) $(GFLAGS) -p $< > $*.F
+	$(COMPILE.F) -o $% $*.F
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+
+#	FORTRAN section. ratfor.
+RFLAGS=
+COMPILE.r=$(FC) $(FFLAGS) $(RFLAGS)  -c
+LINK.r=$(FC) $(FFLAGS) $(RFLAGS) $(LDFLAGS) 
+.r:
+	$(LINK.r) -o $@ $< $(LDLIBS)
+.r~:
+	$(GET) $(GFLAGS) -p $< > $*.r
+	$(LINK.r) -o $@ $*.r $(LDLIBS)
+.r.o:
+	$(COMPILE.r) $(OUTPUT_OPTION) $<
+.r~.o:
+	$(GET) $(GFLAGS) -p $< > $*.r
+	$(COMPILE.r) $(OUTPUT_OPTION) $*.r
+.r.a:
+	$(COMPILE.r) -o $% $<
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+.r~.a:
+	$(GET) $(GFLAGS) -p $< > $*.r
+	$(COMPILE.r) -o $% $*.r
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+
+#	FORTRAN 90 section.
+F90C=f90
+F90FLAGS=
+COMPILE.f90=$(F90C) $(F90FLAGS) -c
+LINK.f90=$(F90C) $(F90FLAGS) $(LDFLAGS)
+COMPILE.ftn=$(F90C) $(F90FLAGS) -c
+LINK.ftn=$(F90C) $(F90FLAGS) $(LDFLAGS)
+.f90:
+	$(LINK.f90) -o $@ $< $(LDLIBS)
+.f90~:
+	$(GET) $(GFLAGS) -p $< > $*.f90
+	$(LINK.f90) -o $@ $*.f90 $(LDLIBS)
+.f90.o:
+	$(COMPILE.f90) $(OUTPUT_OPTION) $<
+.f90~.o:
+	$(GET) $(GFLAGS) -p $< > $*.f90
+	$(COMPILE.f90) $(OUTPUT_OPTION) $*.f90
+.f90.a:
+	$(COMPILE.f90) -o $% $<
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+.f90~.a:
+	$(GET) $(GFLAGS) -p $< > $*.f90
+	$(COMPILE.f90) -o $% $*.f90
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+.ftn:
+	$(LINK.ftn) -o $@ $< $(LDLIBS)
+.ftn~:
+	$(GET) $(GFLAGS) -p $< > $*.ftn
+	$(LINK.ftn) -o $@ $*.ftn $(LDLIBS)
+.ftn.o:
+	$(COMPILE.ftn) $(OUTPUT_OPTION) $<
+.ftn~.o:
+	$(GET) $(GFLAGS) -p $< > $*.ftn
+	$(COMPILE.ftn) $(OUTPUT_OPTION) $*.ftn
+.ftn.a:
+	$(COMPILE.ftn) -o $% $<
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+.ftn~.a:
+	$(GET) $(GFLAGS) -p $< > $*.ftn
+	$(COMPILE.ftn) -o $% $*.ftn
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+
+#	Modula-2 section.
+M2C=m2c
+M2FLAGS=
+MODFLAGS=
+DEFFLAGS=
+COMPILE.def=$(M2C) $(M2FLAGS) $(DEFFLAGS) 
+COMPILE.mod=$(M2C) $(M2FLAGS) $(MODFLAGS) 
+.def.sym:
+	$(COMPILE.def) -o $@ $<
+.def~.sym:
+	$(GET) $(GFLAGS) -p $< > $*.def
+	$(COMPILE.def) -o $@ $*.def
+.mod:
+	$(COMPILE.mod) -o $@ -e $@ $<
+.mod~:
+	$(GET) $(GFLAGS) -p $< > $*.mod
+	$(COMPILE.mod) -o $@ -e $@ $*.mod
+.mod.o:
+	$(COMPILE.mod) -o $@ $<
+.mod~.o:
+	$(GET) $(GFLAGS) -p $< > $*.mod
+	$(COMPILE.mod) -o $@ $*.mod
+.mod.a:
+	$(COMPILE.mod) -o $% $<
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+.mod~.a:
+	$(GET) $(GFLAGS) -p $< > $*.mod
+	$(COMPILE.mod) -o $% $*.mod
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+
+#	Pascal section.
+PC=pc
+PFLAGS=
+COMPILE.p=$(PC) $(PFLAGS) $(CPPFLAGS)  -c
+LINK.p=$(PC) $(PFLAGS) $(CPPFLAGS) $(LDFLAGS) 
+.p:
+	$(LINK.p) -o $@ $< $(LDLIBS)
+.p~:
+	$(GET) $(GFLAGS) -p $< > $*.p
+	$(LINK.p) -o $@ $*.p $(LDLIBS)
+.p.o:
+	$(COMPILE.p) $(OUTPUT_OPTION) $<
+.p~.o:
+	$(GET) $(GFLAGS) -p $< > $*.p
+	$(COMPILE.p) $(OUTPUT_OPTION) $*.p
+.p.a:
+	$(COMPILE.p) -o $% $<
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+.p~.a:
+	$(GET) $(GFLAGS) -p $< > $*.p
+	$(COMPILE.p) -o $% $*.p
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+
+#	Assembly section.
+AS=as
+ASFLAGS=
+COMPILE.s=$(AS) $(ASFLAGS) 
+COMPILE.S=$(CC) $(ASFLAGS) $(CPPFLAGS)  -c
+.s.o:
+	$(COMPILE.s) -o $@ $<
+.s~.o:
+	$(GET) $(GFLAGS) -p $< > $*.s
+	$(COMPILE.s) -o $@ $*.s
+.s.a:
+	$(COMPILE.s) -o $% $<
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+.s~.a:
+	$(GET) $(GFLAGS) -p $< > $*.s
+	$(COMPILE.s) -o $% $*.s
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+.S.o:
+	$(COMPILE.S) -o $@ $<
+.S~.o:
+	$(GET) $(GFLAGS) -p $< > $*.S
+	$(COMPILE.S) -o $@ $*.S
+.S.a:
+	$(COMPILE.S) -o $% $<
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+.S~.a:
+	$(GET) $(GFLAGS) -p $< > $*.S
+	$(COMPILE.S) -o $% $*.S
+	$(AR) $(ARFLAGS) $@ $%
+	$(RM) $%
+
+#	Shell section.
+.sh:
+	$(RM) $@
+	cat $< > $@
+	chmod +x $@
+.sh~:
+	$(GET) $(GFLAGS) -p $< > $*.sh
+	cp $*.sh $@
+	chmod a+x $@
+
+#	NeWS section
+CPS=cps
+CPSFLAGS=
+.cps.h:
+	$(CPS) $(CPSFLAGS) $*.cps
+.cps~.h:
+	$(GET) $(GFLAGS) -p $< > $*.cps
+	$(CPS) $(CPSFLAGS) $*.cps
+
+#	JAVA section
+JAVAC=javac
+JAVACFLAGS=
+.java.class:
+	$(JAVAC) $(JAVACFLAGS) $<
+.java~.class:
+	$(GET) $(GFLAGS) -p $< > $*.java
+	$(JAVAC) $(JAVACFLAGS) $<
+
+#	Miscellaneous section.
+LD=ld
+LDFLAGS=
+LDLIBS=
+MAKE=make
+RM=rm -f
+AR=ar
+ARFLAGS=rv
+GET=get
+GFLAGS=
+
+markfile.o:	markfile
+	echo "static char _sccsid[] = \"`grep @'(#)' markfile`\";" > markfile.c
+	cc -c markfile.c
+	$(RM) markfile.c
+
+SCCSFLAGS=
+SCCSGETFLAGS=-s
+.SCCS_GET:
+	sccs $(SCCSFLAGS) get $(SCCSGETFLAGS) $@ -G$@
+
+.SCCS_GET_POSIX:
+	sccs $(SCCSFLAGS) get $(SCCSGETFLAGS) $@ 
+
+.GET_POSIX:
+	$(GET) $(GFLAGS) s.$@ 
--- /dev/null	2015-05-20 11:04:09.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/common/misc.cc	2015-05-20 11:04:09.774590860 -0400
@@ -0,0 +1,1007 @@
+/*
+ * 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 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)misc.cc 1.50 06/12/12
+ */
+
+#pragma	ident	"@(#)misc.cc	1.34	95/10/04"
+
+/*
+ *	misc.cc
+ *
+ *	This file contains various unclassified routines. Some main groups:
+ *		getname
+ *		Memory allocation
+ *		String handling
+ *		Property handling
+ *		Error message handling
+ *		Make internal state dumping
+ *		main routine support
+ */
+
+/*
+ * Included files
+ */
+#include <errno.h>
+#include <mk/defs.h>
+#include <mksh/macro.h>		/* SETVAR() */
+#include <mksh/misc.h>		/* enable_interrupt() */
+#include <stdarg.h>		/* va_list, va_start(), va_end() */
+#include <vroot/report.h>	/* SUNPRO_DEPENDENCIES */
+
+#if defined(HP_UX) || defined(linux)
+#include <unistd.h>
+#endif
+
+#ifdef TEAMWARE_MAKE_CMN
+#define MAXJOBS_ADJUST_RFE4694000
+
+#ifdef MAXJOBS_ADJUST_RFE4694000
+extern void job_adjust_fini();
+#endif /* MAXJOBS_ADJUST_RFE4694000 */
+#endif /* TEAMWARE_MAKE_CMN */
+
+#if defined(linux)
+#include <time.h>		/* localtime() */
+#endif
+
+/*
+ * Defined macros
+ */
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+
+/*
+ * File table of contents
+ */
+static	void		print_rule(register Name target);
+static	void		print_target_n_deps(register Name target);
+
+/*****************************************
+ *
+ *	getname
+ */
+
+/*****************************************
+ *
+ *	Memory allocation
+ */
+
+/*
+ *	free_chain()
+ *
+ *	frees a chain of Name_vector's
+ *
+ *	Parameters:
+ *		ptr		Pointer to the first element in the chain
+ *				to be freed.
+ *
+ *	Global variables used:
+ */
+void 
+free_chain(Name_vector ptr)
+{
+	if (ptr != NULL) {
+		if (ptr->next != NULL) {
+			free_chain(ptr->next);
+		}
+		free((char *) ptr);
+	}
+}
+
+/*****************************************
+ *
+ *	String manipulation
+ */
+
+/*****************************************
+ *
+ *	Nameblock property handling
+ */
+
+/*****************************************
+ *
+ *	Error message handling
+ */
+
+/*
+ *	fatal(format, args...)
+ *
+ *	Print a message and die
+ *
+ *	Parameters:
+ *		format		printf type format string
+ *		args		Arguments to match the format
+ *
+ *	Global variables used:
+ *		fatal_in_progress Indicates if this is a recursive call
+ *		parallel_process_cnt Do we need to wait for anything?
+ *		report_pwd	Should we report the current path?
+ */
+/*VARARGS*/
+void
+fatal(char * message, ...)
+{
+	va_list args;
+
+	va_start(args, message);
+	(void) fflush(stdout);
+#ifdef DISTRIBUTED
+	(void) fprintf(stderr, catgets(catd, 1, 262, "dmake: Fatal error: "));
+#else
+	(void) fprintf(stderr, catgets(catd, 1, 263, "make: Fatal error: "));
+#endif
+	(void) vfprintf(stderr, message, args);
+	(void) fprintf(stderr, "\n");
+	va_end(args);
+	if (report_pwd) {
+		(void) fprintf(stderr,
+			       catgets(catd, 1, 156, "Current working directory %s\n"),
+			       get_current_path());
+	}
+	(void) fflush(stderr);
+	if (fatal_in_progress) {
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+		exit_status = 1;
+#endif
+		exit(1);
+	}
+	fatal_in_progress = true;
+#ifdef TEAMWARE_MAKE_CMN
+	/* Let all parallel children finish */
+	if ((dmake_mode_type == parallel_mode) &&
+	    (parallel_process_cnt > 0)) {
+		(void) fprintf(stderr,
+			       catgets(catd, 1, 157, "Waiting for %d %s to finish\n"),
+			       parallel_process_cnt,
+			       parallel_process_cnt == 1 ?
+			       catgets(catd, 1, 158, "job") : catgets(catd, 1, 159, "jobs"));
+		(void) fflush(stderr);
+	}
+
+	while (parallel_process_cnt > 0) {
+#ifdef DISTRIBUTED
+		if (dmake_mode_type == distributed_mode) {
+			(void) await_dist(false);
+		} else {
+			await_parallel(true);
+		}
+#else
+		await_parallel(true);
+#endif
+		finish_children(false);
+	}
+#endif
+
+#if defined (TEAMWARE_MAKE_CMN) && defined (MAXJOBS_ADJUST_RFE4694000)
+	job_adjust_fini();
+#endif
+
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+	exit_status = 1;
+#endif
+	exit(1);
+}
+
+/*
+ *	warning(format, args...)
+ *
+ *	Print a message and continue.
+ *
+ *	Parameters:
+ *		format		printf type format string
+ *		args		Arguments to match the format
+ *
+ *	Global variables used:
+ *		report_pwd	Should we report the current path?
+ */
+/*VARARGS*/
+void
+warning(char * message, ...)
+{
+	va_list args;
+
+	va_start(args, message);
+	(void) fflush(stdout);
+#ifdef DISTRIBUTED
+	(void) fprintf(stderr, catgets(catd, 1, 264, "dmake: Warning: "));
+#else
+	(void) fprintf(stderr, catgets(catd, 1, 265, "make: Warning: "));
+#endif
+	(void) vfprintf(stderr, message, args);
+	(void) fprintf(stderr, "\n");
+	va_end(args);
+	if (report_pwd) {
+		(void) fprintf(stderr,
+			       catgets(catd, 1, 161, "Current working directory %s\n"),
+			       get_current_path());
+	}
+	(void) fflush(stderr);
+}
+
+/*
+ *	time_to_string(time)
+ *
+ *	Take a numeric time value and produce
+ *	a proper string representation.
+ *
+ *	Return value:
+ *				The string representation of the time
+ *
+ *	Parameters:
+ *		time		The time we need to translate
+ *
+ *	Global variables used:
+ */
+char *
+time_to_string(const timestruc_t &time)
+{
+	struct tm		*tm;
+	char			buf[128];
+
+        if (time == file_doesnt_exist) {
+                return catgets(catd, 1, 163, "File does not exist");
+        }
+        if (time == file_max_time) {
+                return catgets(catd, 1, 164, "Younger than any file");
+        }
+	tm = localtime(&time.tv_sec);
+	strftime(buf, sizeof (buf), NOCATGETS("%c %Z"), tm);
+        buf[127] = (int) nul_char;
+        return strdup(buf);
+}
+
+/*
+ *	get_current_path()
+ *
+ *	Stuff current_path with the current path if it isnt there already.
+ *
+ *	Parameters:
+ *
+ *	Global variables used:
+ */
+char *
+get_current_path(void)
+{
+	char			pwd[(MAXPATHLEN * MB_LEN_MAX)];
+	static char		*current_path;
+
+	if (current_path == NULL) {
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+		getcwd(pwd, sizeof(pwd));
+#else
+		(void) getwd(pwd);
+#endif
+		if (pwd[0] == (int) nul_char) {
+			pwd[0] = (int) slash_char;
+			pwd[1] = (int) nul_char;
+#ifdef DISTRIBUTED
+			current_path = strdup(pwd);
+		} else if (IS_EQUALN(pwd, NOCATGETS("/tmp_mnt"), 8)) {
+			current_path = strdup(pwd + 8);
+		} else {
+			current_path = strdup(pwd);
+		}
+#else
+		}
+		current_path = strdup(pwd);
+#endif
+	}
+	return current_path;
+}
+
+/*****************************************
+ *
+ *	Make internal state dumping
+ *
+ *	This is a set  of routines for dumping the internal make state
+ *	Used for the -p option
+ */
+
+/*
+ *	dump_make_state()
+ *
+ *	Dump make's internal state to stdout
+ *
+ *	Parameters:
+ *
+ *	Global variables used:
+ *		svr4 			Was ".SVR4" seen in makefile?
+ *		svr4_name		The Name ".SVR4", printed
+ *		posix			Was ".POSIX" seen in makefile?
+ *		posix_name		The Name ".POSIX", printed
+ *		default_rule		Points to the .DEFAULT rule
+ *		default_rule_name	The Name ".DEFAULT", printed
+ *		default_target_to_build	The first target to print
+ *		dot_keep_state		The Name ".KEEP_STATE", printed
+ *		dot_keep_state_file	The Name ".KEEP_STATE_FILE", printed
+ *		hashtab			The make hash table for Name blocks
+ *		ignore_errors		Was ".IGNORE" seen in makefile?
+ *		ignore_name		The Name ".IGNORE", printed
+ *		keep_state		Was ".KEEP_STATE" seen in makefile?
+ *		percent_list		The list of % rules
+ *		precious		The Name ".PRECIOUS", printed
+ *		sccs_get_name		The Name ".SCCS_GET", printed
+ *		sccs_get_posix_name	The Name ".SCCS_GET_POSIX", printed
+ *		get_name		The Name ".GET", printed
+ *		get_posix_name		The Name ".GET_POSIX", printed
+ *		sccs_get_rule		Points to the ".SCCS_GET" rule
+ *		silent			Was ".SILENT" seen in makefile?
+ *		silent_name		The Name ".SILENT", printed
+ *		suffixes		The suffix list from ".SUFFIXES"
+ *		suffixes_name		The Name ".SUFFIX", printed
+ */
+void
+dump_make_state(void)
+{
+	Name_set::iterator	p, e;
+	register Property	prop;
+	register Dependency	dep;
+	register Cmd_line	rule;
+	Percent			percent, percent_depe;
+
+	/* Default target */
+	if (default_target_to_build != NULL) {
+		print_rule(default_target_to_build);
+	}
+	(void) printf("\n");
+
+	/* .POSIX */
+	if (posix) {
+		(void) printf("%s:\n", posix_name->string_mb);
+	}
+
+	/* .DEFAULT */
+	if (default_rule != NULL) {
+		(void) printf("%s:\n", default_rule_name->string_mb);
+		for (rule = default_rule; rule != NULL; rule = rule->next) {
+			(void) printf("\t%s\n", rule->command_line->string_mb);
+		}
+	}
+
+	/* .IGNORE */
+	if (ignore_errors) {
+		(void) printf("%s:\n", ignore_name->string_mb);
+	}
+
+	/* .KEEP_STATE: */
+	if (keep_state) {
+		(void) printf("%s:\n\n", dot_keep_state->string_mb);
+	}
+
+	/* .PRECIOUS */
+	(void) printf("%s:", precious->string_mb);
+	for (p = hashtab.begin(), e = hashtab.end(); p != e; p++) {
+			if ((p->stat.is_precious) || (all_precious)) {
+				(void) printf(" %s", p->string_mb);
+			}
+	}
+	(void) printf("\n");
+
+	/* .SCCS_GET */
+	if (sccs_get_rule != NULL) {
+		(void) printf("%s:\n", sccs_get_name->string_mb);
+		for (rule = sccs_get_rule; rule != NULL; rule = rule->next) {
+			(void) printf("\t%s\n", rule->command_line->string_mb);
+		}
+	}
+
+	/* .SILENT */
+	if (silent) {
+		(void) printf("%s:\n", silent_name->string_mb);
+	}
+
+	/* .SUFFIXES: */
+	(void) printf("%s:", suffixes_name->string_mb);
+	for (dep = suffixes; dep != NULL; dep = dep->next) {
+		(void) printf(" %s", dep->name->string_mb);
+		build_suffix_list(dep->name);
+	}
+	(void) printf("\n\n");
+
+	/* % rules */
+	for (percent = percent_list;
+	     percent != NULL;
+	     percent = percent->next) {
+		(void) printf("%s:",
+			      percent->name->string_mb);
+		
+		for (percent_depe = percent->dependencies;
+		     percent_depe != NULL;
+		     percent_depe = percent_depe->next) {
+			(void) printf(" %s", percent_depe->name->string_mb);
+		}
+		
+		(void) printf("\n");
+
+		for (rule = percent->command_template;
+		     rule != NULL;
+		     rule = rule->next) {
+			(void) printf("\t%s\n", rule->command_line->string_mb);
+		}
+	}
+
+	/* Suffix rules */
+	for (p = hashtab.begin(), e = hashtab.end(); p != e; p++) {
+			Wstring wcb(p);
+			if (wcb.get_string()[0] == (int) period_char) {
+				print_rule(p);
+			}
+	}
+
+	/* Macro assignments */
+	for (p = hashtab.begin(), e = hashtab.end(); p != e; p++) {
+			if (((prop = get_prop(p->prop, macro_prop)) != NULL) &&
+			    (prop->body.macro.value != NULL)) {
+				(void) printf("%s", p->string_mb);
+				print_value(prop->body.macro.value,
+					    (Daemon) prop->body.macro.daemon);
+			}
+	}
+	(void) printf("\n");
+
+	/* Conditional macro assignments */
+	for (p = hashtab.begin(), e = hashtab.end(); p != e; p++) {
+			for (prop = get_prop(p->prop, conditional_prop);
+			     prop != NULL;
+			     prop = get_prop(prop->next, conditional_prop)) {
+				(void) printf("%s := %s",
+					      p->string_mb,
+					      prop->body.conditional.name->
+					      string_mb);
+				if (prop->body.conditional.append) {
+					printf(" +");
+				}
+				else {
+					printf(" ");
+				}
+				print_value(prop->body.conditional.value,
+					    no_daemon);
+			}
+	}
+	(void) printf("\n");
+
+	/* All other dependencies */
+	for (p = hashtab.begin(), e = hashtab.end(); p != e; p++) {
+			if (p->colons != no_colon) {
+				print_rule(p);
+			}
+	}
+	(void) printf("\n");
+}
+
+/*
+ *	print_rule(target)
+ *
+ *	Print the rule for one target
+ *
+ *	Parameters:
+ *		target		Target we print rule for
+ *
+ *	Global variables used:
+ */
+static void
+print_rule(register Name target)
+{
+	register Cmd_line	rule;
+	register Property	line;
+	register Dependency	dependency;
+
+	if (target->dependency_printed ||
+	    ((line = get_prop(target->prop, line_prop)) == NULL) ||
+	    ((line->body.line.command_template == NULL) &&
+	     (line->body.line.dependencies == NULL))) {
+		return;
+	}
+	target->dependency_printed = true;
+
+	(void) printf("%s:", target->string_mb);
+
+	for (dependency = line->body.line.dependencies;
+	     dependency != NULL;
+	     dependency = dependency->next) {
+		(void) printf(" %s", dependency->name->string_mb);
+	}
+
+	(void) printf("\n");
+
+	for (rule = line->body.line.command_template;
+	     rule != NULL;
+	     rule = rule->next) {
+		(void) printf("\t%s\n", rule->command_line->string_mb);
+	}
+}
+
+void
+dump_target_list(void)
+{
+	Name_set::iterator	p, e;
+	Wstring	str;
+
+	for (p = hashtab.begin(), e = hashtab.end(); p != e; p++) {
+			str.init(p);
+			wchar_t * wcb = str.get_string();
+			if ((p->colons != no_colon) &&
+			    ((wcb[0] != (int) period_char) ||
+			     ((wcb[0] == (int) period_char) &&
+			      (wschr(wcb, (int) slash_char))))) {
+				print_target_n_deps(p);
+			}
+	}
+}
+
+static void
+print_target_n_deps(register Name target)
+{
+	register Cmd_line	rule;
+	register Property	line;
+	register Dependency	dependency;
+
+	if (target->dependency_printed) {
+		return;
+	}
+	target->dependency_printed = true;
+
+	(void) printf("%s\n", target->string_mb);
+
+	if ((line = get_prop(target->prop, line_prop)) == NULL) {
+		return;
+	}
+	for (dependency = line->body.line.dependencies;
+	     dependency != NULL;
+	     dependency = dependency->next) {
+		if (!dependency->automatic) {
+			print_target_n_deps(dependency->name);
+		}
+	}
+}
+
+/*****************************************
+ *
+ *	main() support
+ */
+
+/*
+ *	load_cached_names()
+ *
+ *	Load the vector of cached names
+ *
+ *	Parameters:
+ *
+ *	Global variables used:
+ *		Many many pointers to Name blocks.
+ */
+void
+load_cached_names(void)
+{
+	char		*cp;
+	Name		dollar;
+
+	/* Load the cached_names struct */
+	MBSTOWCS(wcs_buffer, NOCATGETS(".BUILT_LAST_MAKE_RUN"));
+	built_last_make_run = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS("@"));
+	c_at = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS(" *conditionals* "));
+	conditionals = GETNAME(wcs_buffer, FIND_LENGTH);
+	/*
+	 * A version of make was released with NSE 1.0 that used
+	 * VERSION-1.1 but this version is identical to VERSION-1.0.
+	 * The version mismatch code makes a special case for this
+	 * situation.  If the version number is changed from 1.0
+	 * it should go to 1.2.
+	 */
+	MBSTOWCS(wcs_buffer, NOCATGETS("VERSION-1.0"));
+	current_make_version = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS(".SVR4"));
+	svr4_name = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS(".POSIX"));
+	posix_name = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS(".DEFAULT"));
+	default_rule_name = GETNAME(wcs_buffer, FIND_LENGTH);
+#ifdef NSE
+	MBSTOWCS(wcs_buffer, NOCATGETS(".DERIVED_SRC"));
+        derived_src= GETNAME(wcs_buffer, FIND_LENGTH);
+#endif
+	MBSTOWCS(wcs_buffer, NOCATGETS("$"));
+	dollar = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS(".DONE"));
+	done = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS("."));
+	dot = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS(".KEEP_STATE"));
+	dot_keep_state = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS(".KEEP_STATE_FILE"));
+	dot_keep_state_file = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS(""));
+	empty_name = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS(" FORCE"));
+	force = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS("HOST_ARCH"));
+	host_arch = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS("HOST_MACH"));
+	host_mach = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS(".IGNORE"));
+	ignore_name = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS(".INIT"));
+	init = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS(".LOCAL"));
+	localhost_name = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS(".make.state"));
+	make_state = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS("MAKEFLAGS"));
+	makeflags = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS(".MAKE_VERSION"));
+	make_version = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS(".NO_PARALLEL"));
+	no_parallel_name = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS(".NOT_AUTO"));
+	not_auto = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS(".PARALLEL"));
+	parallel_name = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS("PATH"));
+	path_name = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS("+"));
+	plus = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS(".PRECIOUS"));
+	precious = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS("?"));
+	query = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS("^"));
+	hat = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS(".RECURSIVE"));
+	recursive_name = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS(".SCCS_GET"));
+	sccs_get_name = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS(".SCCS_GET_POSIX"));
+	sccs_get_posix_name = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS(".GET"));
+	get_name = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS(".GET_POSIX"));
+	get_posix_name = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS("SHELL"));
+	shell_name = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS(".SILENT"));
+	silent_name = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS(".SUFFIXES"));
+	suffixes_name = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, SUNPRO_DEPENDENCIES);
+	sunpro_dependencies = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS("TARGET_ARCH"));
+	target_arch = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS("TARGET_MACH"));
+	target_mach = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS("VIRTUAL_ROOT"));
+	virtual_root = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS("VPATH"));
+	vpath_name = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, NOCATGETS(".WAIT"));
+	wait_name = GETNAME(wcs_buffer, FIND_LENGTH);
+
+	wait_name->state = build_ok;
+
+	/* Mark special targets so that the reader treats them properly */
+	svr4_name->special_reader = svr4_special;
+	posix_name->special_reader = posix_special;
+	built_last_make_run->special_reader = built_last_make_run_special;
+	default_rule_name->special_reader = default_special;
+#ifdef NSE
+        derived_src->special_reader= derived_src_special;
+#endif
+	dot_keep_state->special_reader = keep_state_special;
+	dot_keep_state_file->special_reader = keep_state_file_special;
+	ignore_name->special_reader = ignore_special;
+	make_version->special_reader = make_version_special;
+	no_parallel_name->special_reader = no_parallel_special;
+	parallel_name->special_reader = parallel_special;
+	localhost_name->special_reader = localhost_special;
+	precious->special_reader = precious_special;
+	sccs_get_name->special_reader = sccs_get_special;
+	sccs_get_posix_name->special_reader = sccs_get_posix_special;
+	get_name->special_reader = get_special;
+	get_posix_name->special_reader = get_posix_special;
+	silent_name->special_reader = silent_special;
+	suffixes_name->special_reader = suffixes_special;
+
+	/* The value of $$ is $ */
+	(void) SETVAR(dollar, dollar, false);
+	dollar->dollar = false;
+
+	/* Set the value of $(SHELL) */
+	#ifdef HP_UX
+	MBSTOWCS(wcs_buffer, NOCATGETS("/bin/posix/sh"));
+	#else
+	#if defined(SUN5_0)
+	if (posix) {
+	  MBSTOWCS(wcs_buffer, NOCATGETS("/usr/xpg4/bin/sh"));
+	} else {
+	  MBSTOWCS(wcs_buffer, NOCATGETS("/bin/sh"));
+	}
+	#else  /* ^SUN5_0 */
+	MBSTOWCS(wcs_buffer, NOCATGETS("/bin/sh"));
+	#endif /* ^SUN5_0 */
+	#endif
+	(void) SETVAR(shell_name, GETNAME(wcs_buffer, FIND_LENGTH), false);
+
+	/*
+	 * Use " FORCE" to simulate a FRC dependency for :: type
+	 * targets with no dependencies.
+	 */
+	(void) append_prop(force, line_prop);
+	force->stat.time = file_max_time;
+
+	/* Make sure VPATH is defined before current dir is read */
+	if ((cp = getenv(vpath_name->string_mb)) != NULL) {
+		MBSTOWCS(wcs_buffer, cp);
+		(void) SETVAR(vpath_name,
+			      GETNAME(wcs_buffer, FIND_LENGTH),
+			      false);
+	}
+
+	/* Check if there is NO PATH variable. If not we construct one. */
+	if (getenv(path_name->string_mb) == NULL) {
+		vroot_path = NULL;
+		add_dir_to_path(NOCATGETS("."), &vroot_path, -1);
+		add_dir_to_path(NOCATGETS("/bin"), &vroot_path, -1);
+		add_dir_to_path(NOCATGETS("/usr/bin"), &vroot_path, -1);
+	}
+}
+
+/* 
+ * iterate on list of conditional macros in np, and place them in 
+ * a String_rec starting with, and separated by the '$' character.
+ */
+void
+cond_macros_into_string(Name np, String_rec *buffer)
+{
+	Macro_list	macro_list;
+
+	/* 
+	 * Put the version number at the start of the string
+	 */
+	MBSTOWCS(wcs_buffer, DEPINFO_FMT_VERSION);
+	append_string(wcs_buffer, buffer, FIND_LENGTH);
+	/* 
+	 * Add the rest of the conditional macros to the buffer
+	 */
+	if (np->depends_on_conditional){
+		for (macro_list = np->conditional_macro_list; 
+		     macro_list != NULL; macro_list = macro_list->next){
+			append_string(macro_list->macro_name, buffer, 
+				FIND_LENGTH);
+			append_char((int) equal_char, buffer);
+			append_string(macro_list->value, buffer, FIND_LENGTH);
+			append_char((int) dollar_char, buffer);
+		}
+	}
+}
+/*
+ *	Copyright (c) 1987-1992 Sun Microsystems, Inc.  All Rights Reserved.
+ *	Sun considers its source code as an unpublished, proprietary
+ *	trade secret, and it is available only under strict license
+ *	provisions.  This copyright notice is placed here only to protect
+ *	Sun in the event the source is deemed a published work.  Dissassembly,
+ *	decompilation, or other means of reducing the object code to human
+ *	readable form is prohibited by the license agreement under which
+ *	this code is provided to the user or company in possession of this
+ *	copy.
+ *	RESTRICTED RIGHTS LEGEND: Use, duplication, or disclosure by the
+ *	Government is subject to restrictions as set forth in subparagraph
+ *	(c)(1)(ii) of the Rights in Technical Data and Computer Software
+ *	clause at DFARS 52.227-7013 and in similar clauses in the FAR and
+ *	NASA FAR Supplement.
+ *
+ * 1.3 91/09/30
+ */
+
+
+/* Some includes are commented because of the includes at the beginning */
+/* #include <signal.h> */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+/* #include <string.h> */
+#include <unistd.h>
+#include <stdlib.h>
+/* #include <stdio.h> */
+/* #include <avo/find_dir.h> */
+/* #ifndef TEAMWARE_MAKE_CMN
+#include <avo/find_dir.h>
+#endif */
+
+/* Routines to find the base directory name from which the various components
+ * -executables, *crt* libraries etc will be accessed
+ */
+
+/* This routine checks to see if a given filename is an executable or not.
+   Logically similar to the csh statement : if  ( -x $i && ! -d $i )
+ */
+
+static int
+check_if_exec(char *file)
+{
+        struct stat stb;
+        if (stat(file, &stb) < 0) {
+                return ( -1);
+        }
+        if (S_ISDIR(stb.st_mode)) {
+                return (-1);
+        }
+        if (!(stb.st_mode & S_IEXEC)) {
+                return ( -1);
+        }
+        return (0);
+}
+
+/* resolve - check for specified file in specified directory
+ *	sets up dir, following symlinks.
+ *	returns zero for success, or
+ *	-1 for error (with errno set properly)
+ */
+static int
+resolve (char	*indir,	/* search directory */
+	 char	*cmd,	/* search for name */
+	 char	*dir,	/* directory buffer */
+	 char	**run)	/* resultion name ptr ptr */
+{
+    char               *p;
+    int                 rv = -1;
+    int                 sll;
+    char                symlink[MAXPATHLEN + 1];
+
+    do {
+	errno = ENAMETOOLONG;
+	if ((strlen (indir) + strlen (cmd) + 2) > (size_t) MAXPATHLEN)
+	    break;
+
+	sprintf(dir, "%s/%s", indir, cmd);
+	if (check_if_exec(dir) != 0)  /* check if dir is an executable */
+	{
+		break;		/* Not an executable program */
+	}
+
+	/* follow symbolic links */
+	while ((sll = readlink (dir, symlink, MAXPATHLEN)) >= 0) {
+	    symlink[sll] = 0;
+	    if (*symlink == '/')
+		strcpy (dir, symlink);
+	    else
+		sprintf (strrchr (dir, '/'), "/%s", symlink);
+	}
+	if (errno != EINVAL)
+	    break;
+
+	p = strrchr (dir, '/');
+	*p++ = 0;
+	if (run)		/* user wants resolution name */
+	    *run = p;
+	rv = 0;			/* complete, with success! */
+
+    } while (0);
+
+    return rv;
+}
+
+/* 
+ *find_run_directory - find executable file in PATH
+ *
+ * PARAMETERS:
+ *	cmd	filename as typed by user (argv[0])
+ *	cwd	buffer from which is read the working directory
+ *		 if first character is '/' or into which is
+ *		 copied working directory name otherwise
+ *	dir	buffer into which is copied program's directory
+ *	pgm	where to return pointer to tail of cmd (may be NULL
+ *		 if not wanted) 
+ *	run	where to return pointer to tail of final resolved
+ *		 name ( dir/run is the program) (may be NULL
+ *		 if not wanted)
+ *	path	user's path from environment
+ *
+ * Note: run and pgm will agree except when symbolic links have
+ *	renamed files
+ *
+ * RETURNS:
+ *	returns zero for success,
+ *	-1 for error (with errno set properly).
+ *
+ * EXAMPLE:
+ *	find_run_directory (argv[0], ".", &charray1, (char **) 0, (char **) 0,
+ *                          getenv(NOGETTEXT("PATH")));
+ */
+extern int
+find_run_directory (char	*cmd,
+		    char	*cwd,
+		    char	*dir,
+		    char	**pgm,
+		    char	**run,
+		    char	*path)
+{
+    int                 rv = 0;
+    char 		*f, *s;
+    int			i;
+    char		tmp_path[MAXPATHLEN];
+
+    if (!cmd || !*cmd || !cwd || !dir) {
+	errno = EINVAL;		/* stupid arguments! */
+	return -1;
+    }
+
+    if (*cwd != '/')
+	if (!(getcwd (cwd, MAXPATHLEN)))
+	    return -1;		/* can not get working directory */
+
+    f = strrchr (cmd, '/');
+    if (pgm)			/* user wants program name */
+	*pgm = f ? f + 1 : cmd;
+
+    /* get program directory */
+    rv = -1;
+    if (*cmd == '/')	/* absname given */
+	rv = resolve ("", cmd + 1, dir, run);
+    else if (f)		/* relname given */
+	rv = resolve (cwd, cmd, dir, run);
+    else {  /* from searchpath */
+	    if (!path || !*path) {	/* if missing or null path */
+		    tmp_path[0] = '.';	/* assume sanity */
+		    tmp_path[1] = '\0';
+	    } else {
+		    strcpy(tmp_path, path);
+	    }
+	f = tmp_path;
+	rv = -1;
+	errno = ENOENT;	/* errno gets this if path empty */
+	while (*f && (rv < 0)) {
+	    s = f;
+	    while (*f && (*f != ':'))
+		++f;
+	    if (*f)
+		*f++ = 0;
+	    if (*s == '/')
+		rv = resolve (s, cmd, dir, run);
+	    else {
+		char                abuf[MAXPATHLEN];
+
+		sprintf (abuf, "%s/%s", cwd, s);
+		rv = resolve (abuf, cmd, dir, run);
+	    }
+	}
+    }
+
+    /* Remove any trailing /. */
+    i = strlen(dir);
+    if ( dir[i-2] == '/' && dir[i-1] == '.') {
+	    dir[i-2] = '\0';
+    }
+
+    return rv;
+}
+
--- /dev/null	2015-05-20 11:04:10.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/common/nse.cc	2015-05-20 11:04:09.981202429 -0400
@@ -0,0 +1,610 @@
+/*
+ * 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 1994 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)nse.cc 1.15 06/12/12
+ */
+
+#pragma	ident	"@(#)nse.cc	1.15	06/12/12"
+
+#ifdef NSE
+
+/*
+ * Included files
+ */
+#include <mk/defs.h>
+#include <mksh/macro.h>		/* expand_value() */
+#include <mksh/misc.h>		/* get_prop() */
+
+/*
+ * This file does some extra checking on behalf of the NSE.
+ * It does some stuff that is analogous to lint in that it
+ * looks for things which may be legal but that give the NSE
+ * trouble.  Currently it looks for:
+ *	1) recursion by cd'ing to a directory specified by a 
+ *	   make variable that is defined from the shell environment.
+ *	2) recursion by cd'ing to a directory specified by a
+ *         make variable that has backquotes in it.
+ *	3) recursion to another makefile in the same directory.
+ *	4) a dependency upon an SCCS file (SCCS/s.*)
+ *	5) backquotes in a file name
+ *	6) a make variable being defined on the command-line that
+ *	   ends up affecting dependencies
+ *	7) wildcards (*[) in dependencies
+ *	8) recursion to the same directory
+ *	9) potential source files on the left-hand-side so
+ *	   that they appear as derived files
+ *
+ * Things it should look for:
+ *	1) makefiles that are symlinks (why are these a problem?)
+ */
+
+#define TARG_SUFX	"/usr/nse/lib/nse_targ.sufx"
+
+typedef	struct _Nse_suffix	*Nse_suffix, Nse_suffix_rec;
+struct _Nse_suffix {
+	wchar_t			*suffix;	/* The suffix */
+	struct _Nse_suffix	*next;		/* Linked list */
+};
+static Nse_suffix	sufx_hdr;
+static int		our_exit_status;
+
+static void		nse_warning(void);
+static Boolean		nse_gettoken(wchar_t **, wchar_t *);
+
+/*
+ * Given a command that has just recursed to a sub make
+ * try to determine if it cd'ed to a directory that was
+ * defined by a make variable imported from the shell
+ * environment or a variable with backquotes in it.
+ * This routine will find something like:
+ *	cd $(DIR); $(MAKE)
+ * where DIR is imported from the shell environment.
+ * However it well not find:
+ *	CD = cd
+ *		$(CD) $(DIR); $(MAKE)
+ * or
+ *	CD = cd $(DIR)
+ *		$(CD); $(MAKE)
+ *
+ * This routine also checks for recursion to the same
+ * directory.
+ */
+void
+nse_check_cd(Property prop)
+{
+	wchar_t		tok[512];
+	wchar_t		*p;
+	wchar_t		*our_template;
+	int		len;
+	Boolean		cd;
+#ifdef SUNOS4_AND_AFTER
+	String_rec	string;
+#else
+	String		string;
+#endif
+	Name		name;
+	Name		target;
+	struct	Line	*line;
+	struct	Recursive *r;
+	Property	recurse;
+	wchar_t		strbuf[STRING_BUFFER_LENGTH];
+	wchar_t		tmpbuf[STRING_BUFFER_LENGTH];
+
+#ifdef LTEST
+	printf("In nse_check_cd, nse = %d, nse_did_recursion = %d\n", nse, nse_did_recursion);
+#endif
+#ifdef SUNOS4_AND_AFTER
+	if (!nse_did_recursion || !nse) {
+#else
+	if (is_false(nse_did_recursion) || is_false(flag.nse)) {
+#endif
+#ifdef LTEST
+		printf ("returning,  nse = %d,  nse_did_recursion = %d\n", nse, nse_did_recursion);
+#endif
+		return;
+	}
+	line = &prop->body.line;
+#ifdef LTEST
+	printf("string = %s\n", line->command_template->command_line->string_mb);
+#endif
+
+	wscpy(tmpbuf, line->command_template->command_line->string);
+	our_template = tmpbuf;
+	cd = false;
+	while (nse_gettoken(&our_template, tok)) {
+#ifdef LTEST
+		printf("in gettoken loop\n");
+#endif
+#ifdef SUNOS4_AND_AFTER
+		if (IS_WEQUAL(tok, (wchar_t *) "cd")) {
+#else
+		if (is_equal(tok, "cd")) {
+#endif
+			cd = true;
+		} else if (cd && tok[0] == '$') {
+			nse_backquote_seen = NULL;
+			nse_shell_var_used = NULL;
+			nse_watch_vars = true;
+#ifdef SUNOS4_AND_AFTER
+			INIT_STRING_FROM_STACK(string, strbuf);
+			name = GETNAME(tok, FIND_LENGTH);
+#else
+			init_string_from_stack(string, strbuf);
+			name = getname(tok, FIND_LENGTH);
+#endif
+			expand_value(name, &string, false);
+			nse_watch_vars = false;
+
+#ifdef LTEST
+			printf("cd = %d, tok = $\n", cd);
+#endif
+			/*
+			 * Try to trim tok to just
+			 * the variable.
+			 */
+			if (nse_shell_var_used != NULL) {
+				nse_warning();
+				fprintf(stderr, "\tMake invoked recursively by cd'ing to a directory\n\tdefined by the shell environment variable %s\n\tCommand line: %s\n",
+				    nse_shell_var_used->string_mb,
+				    line->command_template->command_line->string_mb);
+			}
+			if (nse_backquote_seen != NULL) {
+				nse_warning();
+				fprintf(stderr, "\tMake invoked recursively by cd'ing to a directory\n\tdefined by a variable (%s) with backquotes in it\n\tCommand line: %s\n",
+				    nse_backquote_seen->string_mb,
+				    line->command_template->command_line->string_mb);
+			}
+			cd = false;
+		} else if (cd && nse_backquotes(tok)) {
+			nse_warning();
+			fprintf(stderr, "\tMake invoked recursively by cd'ing to a directory\n\tspecified by a command in backquotes\n\tCommand line: %s\n",
+			    line->command_template->command_line->string_mb);
+			cd = false;
+		} else {
+			cd = false;
+		}
+	}
+
+	/*
+	 * Now check for recursion to ".".
+	 */
+	if (primary_makefile != NULL) {
+		target = prop->body.line.target;
+		recurse = get_prop(target->prop, recursive_prop);
+		while (recurse != NULL) {
+			r = &recurse->body.recursive;
+#ifdef SUNOS4_AND_AFTER
+			if (IS_WEQUAL(r->directory->string, (wchar_t *) ".") &&
+			    !IS_WEQUAL(r->makefiles->name->string, 
+                            primary_makefile->string)) {
+#else
+			if (is_equal(r->directory->string, ".") &&
+			    !is_equal(r->makefiles->name->string, 
+			    primary_makefile->string)) {
+#endif
+				nse_warning();
+				fprintf(stderr, "\tRecursion to makefile `%s' in the same directory\n\tCommand line: %s\n",
+				    r->makefiles->name->string_mb,
+				    line->command_template->command_line->string_mb);
+			}
+			recurse = get_prop(recurse->next, recursive_prop);
+		}
+	}
+}
+
+/*
+ * Print an NSE make warning line.
+ * If the -P flag was given then consider this a fatal
+ * error, otherwise, just a warning.
+ */
+static void
+nse_warning(void)
+{
+#ifdef SUNOS4_AND_AFTER
+	if (report_dependencies_level > 0) {
+#else
+	if (is_true(flag.report_dependencies)) {
+#endif
+		our_exit_status = 1;
+	}
+	if (primary_makefile != NULL) {
+		fprintf(stderr, "make: NSE warning from makefile %s/%s:\n",
+			get_current_path(), primary_makefile->string_mb);
+	} else {
+		fprintf(stderr, "make: NSE warning from directory %s:\n",
+			get_current_path());
+	}
+}
+
+/*
+ * Get the next whitespace delimited token pointed to by *cp.
+ * Return it in tok.
+ */
+static Boolean
+nse_gettoken(wchar_t **cp, wchar_t *tok)
+{
+	wchar_t		*to;
+	wchar_t		*p;
+
+	p = *cp;
+	while (*p && iswspace(*p)) {
+		p++;
+	}
+	if (*p == '\0') {
+		return false;
+	}
+	to = tok;
+	while (*p && !iswspace(*p)) {
+		*to++ = *p++;
+	}
+	if (*p == '\0') {
+		return false;
+	}
+	*to = '\0';
+	*cp = p;
+	return true;
+}
+
+/*
+ * Given a dependency and a target, see if the dependency
+ * is an SCCS file.  Check for the last component of its name
+ * beginning with "s." and the component before that being "SCCS".
+ * The NSE does not consider a source file to be derived from
+ * an SCCS file.
+ */
+void
+nse_check_sccs(wchar_t *targ, wchar_t *dep)
+{
+	wchar_t		*slash;
+	wchar_t		*p;
+
+#ifdef SUNOS4_AND_AFTER
+	if (!nse) {
+#else
+	if (is_false(flag.nse)) {
+#endif
+		return;
+	}
+#ifdef SUNOS4_AND_AFTER
+	slash = wsrchr(dep, (int) slash_char); 
+#else
+	slash = rindex(dep, '/');
+#endif
+	if (slash == NULL) {
+		return;
+	}
+	if (slash[1] != 's' || slash[2] != '.') {
+		return;
+	}
+
+	/*
+	 * Find the next to last filename component.
+	 */
+	for (p = slash - 1; p >= dep; p--) {
+		if (*p == '/') {
+			break;
+		}
+	}
+	p++;
+#ifdef SUNOS4_AND_AFTER
+	MBSTOWCS(wcs_buffer, "SCCS/");
+	if (IS_WEQUALN(p, wcs_buffer, wslen(wcs_buffer))) {
+#else
+	if (is_equaln(p, "SCCS/", 5)) {
+#endif
+		nse_warning();
+		WCSTOMBS(mbs_buffer, targ);
+		WCSTOMBS(mbs_buffer2, dep);
+		fprintf(stderr, "\tFile `%s' depends upon SCCS file `%s'\n",
+			mbs_buffer, mbs_buffer2);
+	}
+	return;
+}
+
+/*
+ * Given a filename check to see if it has 2 backquotes in it.
+ * Complain about this because the shell expands the backquotes
+ * but make does not so the files always appear to be out of date.
+ */
+void
+nse_check_file_backquotes(wchar_t *file)
+{
+#ifdef SUNOS4_AND_AFTER
+	if (!nse) {
+#else
+	if (is_false(flag.nse)) {
+#endif
+		return;
+	}
+	if (nse_backquotes(file)) {
+		nse_warning();
+		WCSTOMBS(mbs_buffer, file);
+		fprintf(stderr, "\tFilename \"%s\" has backquotes in it\n",
+			mbs_buffer);
+	}
+}
+
+/*
+ * Return true if the string has two backquotes in it.
+ */
+Boolean
+nse_backquotes(wchar_t *str)
+{
+	wchar_t		*bq;
+
+#ifdef SUNOS4_AND_AFTER
+	bq = wschr(str, (int) backquote_char);
+	if (bq) {
+		bq = wschr(&bq[1], (int) backquote_char);
+#else
+	bq = index(str, '`');
+	if (bq) {
+		bq = index(&bq[1], '`');
+#endif
+		if (bq) {
+			return true;
+		}
+	}
+	return false;
+}
+
+/*
+ * A macro that was defined on the command-line was found to affect the
+ * set of dependencies.  The NSE "target explode" will not know about
+ * this and will not get the same set of dependencies.
+ */
+void
+nse_dep_cmdmacro(wchar_t *macro)
+{
+#ifdef SUNOS4_AND_AFTER
+	if (!nse) {
+#else
+	if (is_false(flag.nse)) {
+#endif
+		return;
+	}
+	nse_warning();
+	WCSTOMBS(mbs_buffer, macro);
+	fprintf(stderr, "\tVariable `%s' is defined on the command-line and\n\taffects dependencies\n",
+		mbs_buffer);
+}
+
+/*
+ * A macro that was defined on the command-line was found to
+ * be part of the argument to a cd before a recursive make.
+ * This make cause the make to recurse to different places
+ * depending upon how it is invoked.
+ */
+void
+nse_rule_cmdmacro(wchar_t *macro)
+{
+#ifdef SUNOS4_AND_AFTER
+	if (!nse) {
+#else
+	if (is_false(flag.nse)) {
+#endif
+		return;
+	}
+	nse_warning();
+	WCSTOMBS(mbs_buffer, macro);
+	fprintf(stderr, "\tMake invoked recursively by cd'ing to a directory\n\tspecified by a variable (%s) defined on the command-line\n",
+		mbs_buffer);
+}
+
+/*
+ * A dependency has been found with a wildcard in it.
+ * This causes the NSE problems because the set of dependencies
+ * can change without changing the Makefile.
+ */
+void
+nse_wildcard(wchar_t *targ, wchar_t *dep)
+{
+#ifdef SUNOS4_AND_AFTER
+	if (!nse) {
+#else
+	if (is_false(flag.nse)) {
+#endif
+		return;
+	}
+	nse_warning();
+	WCSTOMBS(mbs_buffer, targ);
+	WCSTOMBS(mbs_buffer2, dep);
+	fprintf(stderr, "\tFile `%s' has a wildcard in dependency `%s'\n",
+		mbs_buffer, mbs_buffer2);
+}
+
+/*
+ * Read in the list of suffixes that are interpreted as source
+ * files.
+ */
+void
+nse_init_source_suffixes(void)
+{
+	FILE		*fp;
+	wchar_t		suffix[100];
+	Nse_suffix	sufx;
+	Nse_suffix	*bpatch;
+
+	fp = fopen(TARG_SUFX, "r");
+	if (fp == NULL) {
+		return;
+	}
+	bpatch = &sufx_hdr;
+	while (fscanf(fp, "%s %*s", suffix) == 1) {
+#ifdef SUNOS4_AND_AFTER
+		sufx = ALLOC(Nse_suffix);  
+		sufx->suffix = wscpy(ALLOC_WC(wslen(suffix) + 1), suffix);
+#else
+		sufx = alloc(Nse_suffix);
+		sufx->suffix = strcpy(malloc(strlen(suffix) + 1), suffix);
+#endif
+		sufx->next = NULL;
+		*bpatch = sufx;
+		bpatch = &sufx->next;
+	}
+	fclose(fp);
+}
+
+/*
+ * Check if a derived file (something with a dependency) appears
+ * to be a source file (by its suffix) but has no rule to build it.
+ * If so, complain.
+ *
+ * This generally arises from the old-style of make-depend that
+ * produces:
+ *	foo.c:	foo.h
+ */
+void
+nse_check_derived_src(Name target, wchar_t *dep, Cmd_line command_template)
+{
+	Nse_suffix	sufx;
+	wchar_t		*suffix;
+	wchar_t		*depsufx;
+
+#ifdef SUNOS4_AND_AFTER
+	if (!nse) {
+#else
+	if (is_false(flag.nse)) {
+#endif
+		return;
+	}
+#ifdef SUNOS4_AND_AFTER
+	if (target->stat.is_derived_src) {
+#else
+	if (is_true(target->stat.is_derived_src)) {
+#endif
+		return;
+	}
+	if (command_template != NULL) {
+		return;
+	}
+#ifdef SUNOS4_AND_AFTER
+	suffix = wsrchr(target->string, (int) period_char ); 
+#else
+	suffix = rindex(target->string, '.');
+#endif
+	if (suffix != NULL) {
+		for (sufx = sufx_hdr; sufx != NULL; sufx = sufx->next) {
+#ifdef SUNOS4_AND_AFTER
+			if (IS_WEQUAL(sufx->suffix, suffix)) {
+#else
+			if (is_equal(sufx->suffix, suffix)) {
+#endif
+				nse_warning();
+				WCSTOMBS(mbs_buffer, dep);
+				fprintf(stderr, "\tProbable source file `%s' appears as a derived file\n\tas it depends upon file `%s', but there is\n\tno rule to build it\n",
+					target->string_mb, mbs_buffer);
+				break;
+			}
+		}
+	}
+}
+
+/*
+ * See if a target is a potential source file and has no
+ * dependencies and no rule but shows up on the right-hand
+ * side.  This tends to occur from old "make depend" output.
+ */
+void
+nse_check_no_deps_no_rule(Name target, Property line, Property command)
+{
+	Nse_suffix	sufx;
+	wchar_t		*suffix;
+
+#ifdef SUNOS4_AND_AFTER
+	if (!nse) {
+#else
+	if (is_false(flag.nse)) {
+#endif
+		return;
+	}
+#ifdef SUNOS4_AND_AFTER
+	if (target->stat.is_derived_src) {
+#else
+	if (is_true(target->stat.is_derived_src)) {
+#endif
+		return;
+	}
+	if (line != NULL && line->body.line.dependencies != NULL) {
+		return;
+	}
+#ifdef SUNOS4_AND_AFTER
+	if (command->body.line.sccs_command) {
+#else
+	if (is_true(command->body.line.sccs_command)) {
+#endif
+		return;
+	}
+#ifdef SUNOS4_AND_AFTER
+	suffix = wsrchr(target->string, (int) period_char); 
+#else
+	suffix = rindex(target->string, '.');
+#endif
+	if (suffix != NULL) {
+		for (sufx = sufx_hdr; sufx != NULL; sufx = sufx->next) {
+#ifdef SUNOS4_AND_AFTER
+			if (IS_WEQUAL(sufx->suffix, suffix)) {
+#else
+			if (is_equal(sufx->suffix, suffix)) {
+#endif
+				if (command->body.line.command_template == NULL) {
+					nse_warning();
+					fprintf(stderr, "\tProbable source file `%s' appears as a derived file because\n\tit is on the left-hand side, but it has no dependencies and\n\tno rule to build it\n",
+						target->string_mb);
+				}
+			}
+		}
+	} 
+} 
+
+/*
+ * Detected a situation where a recursive make derived a file
+ * without using a makefile.
+ */
+void
+nse_no_makefile(Name target)
+{
+#ifdef SUNOS4_AND_AFTER
+	if (!nse) {
+#else
+	if (is_false(flag.nse)) {
+#endif
+		return;
+	}
+	nse_warning();
+	fprintf(stderr, "Recursive make to derive %s did not use a makefile\n",
+		target->string_mb);
+}
+
+/*
+ * Return the NSE exit status.
+ * If the -P flag was given then a warning is considered fatal
+ */
+int
+nse_exit_status(void)
+{
+	return our_exit_status;
+}
+#endif
--- /dev/null	2015-05-20 11:04:10.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/common/nse_printdep.cc	2015-05-20 11:04:10.206587851 -0400
@@ -0,0 +1,517 @@
+/*
+ * 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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)nse_printdep.cc 1.18 06/12/12
+ */
+
+#pragma	ident	"@(#)nse_printdep.cc	1.18	06/12/12"
+
+/*
+ * Included files
+ */
+#include <mk/defs.h>
+#include <mksh/misc.h>		/* get_prop() */
+
+/*
+ * File table of contents
+ */
+void   print_dependencies(register Name target, register Property line);
+static void	print_deps(register Name target, register Property line);
+static void	print_more_deps(Name target, Name name);
+static void	print_filename(Name name);
+static Boolean	should_print_dep(Property line);
+static void	print_forest(Name target);
+static void	print_deplist(Dependency head);
+void		print_value(register Name value, Daemon daemon);
+static void	print_rule(register Name target);
+static	void	print_rec_info(Name target);
+static Boolean	is_out_of_date(Property line);
+extern void depvar_print_results (void);
+extern int printf (const char *, ...);
+extern int _flsbuf (unsigned int, FILE *);
+
+/*
+ *	print_dependencies(target, line)
+ *
+ *	Print all the dependencies of a target. First print all the Makefiles.
+ *	Then print all the dependencies. Finally, print all the .INIT
+ *	dependencies.
+ *
+ *	Parameters:
+ *		target		The target we print dependencies for
+ *		line		We get the dependency list from here
+ *
+ *	Global variables used:
+ *		done		The Name ".DONE"
+ *		init		The Name ".INIT"
+ *		makefiles_used	List of all makefiles read
+ */
+void
+print_dependencies(register Name target, register Property line)
+{
+	Dependency	dp;
+	static Boolean	makefiles_printed = false;
+
+#ifdef SUNOS4_AND_AFTER
+	if (target_variants) {
+#else
+	if (is_true(flag.target_variants)) {
+#endif
+		depvar_print_results();
+	}
+	
+	if (!makefiles_printed) {
+		/*
+		 * Search the makefile list for the primary makefile,
+		 * then print it and its inclusions.  After that go back
+		 * and print the default.mk file and its inclusions.
+		 */
+		for (dp = makefiles_used; dp != NULL; dp = dp->next) {
+			if (dp->name == primary_makefile) {
+				break;
+			}
+		}
+		if (dp) {
+			print_deplist(dp);
+			for (dp = makefiles_used; dp != NULL; dp = dp->next) {
+				if (dp->name == primary_makefile) {
+					break;
+				}
+				(void)printf(" %s", dp->name->string_mb);
+			}
+		}
+		(void) printf("\n");
+		makefiles_printed = true;
+	}
+	print_deps(target, line);
+#ifdef SUNOS4_AND_AFTER
+/*
+	print_more_deps(target, init);
+	print_more_deps(target, done);
+ */
+	if (target_variants) {
+#else
+	print_more_deps(target, cached_names.init);
+	print_more_deps(target, cached_names.done);
+	if (is_true(flag.target_variants)) {
+#endif
+		print_forest(target);
+	}
+}
+
+/*
+ *	print_more_deps(target, name)
+ *
+ *	Print some special dependencies.
+ *	These are the dependencies for the .INIT and .DONE targets.
+ *
+ *	Parameters:
+ *		target		Target built during make run
+ *		name		Special target to print dependencies for
+ *
+ *	Global variables used:
+ */
+static void
+print_more_deps(Name target, Name name)
+{
+	Property	line;
+	register Dependency	dependencies;
+
+	line = get_prop(name->prop, line_prop);
+	if (line != NULL && line->body.line.dependencies != NULL) {
+		(void) printf("%s:\t", target->string_mb);
+		print_deplist(line->body.line.dependencies);
+		(void) printf("\n");
+		for (dependencies= line->body.line.dependencies;
+		     dependencies != NULL;
+		     dependencies= dependencies->next) {
+	                 print_deps(dependencies->name,
+				 get_prop(dependencies->name->prop, line_prop));
+		}
+	}
+}
+
+/*
+ *	print_deps(target, line, go_recursive)
+ *
+ *	Print a regular dependency list.  Append to this information which
+ *	indicates whether or not the target is recursive.
+ *
+ *	Parameters:
+ *		target		target to print dependencies for
+ *		line		We get the dependency list from here
+ *		go_recursive	Should we show all dependencies recursively?
+ *
+ *	Global variables used:
+ *		recursive_name	The Name ".RECURSIVE", printed
+ */
+static void
+print_deps(register Name target, register Property line)
+{
+	register Dependency	dep;
+
+#ifdef SUNOS4_AND_AFTER
+	if ((target->dependency_printed) ||
+	    (target == force)) {
+#else
+	if (is_true(target->dependency_printed)) {
+#endif
+		return;
+	}
+	target->dependency_printed = true;
+
+	/* only print entries that are actually derived and are not leaf
+	 * files and are not the result of sccs get.
+	 */
+	if (should_print_dep(line)) {
+#ifdef NSE
+		nse_check_no_deps_no_rule(target, line, line);
+#endif
+		if ((report_dependencies_level == 2) ||
+		    (report_dependencies_level == 4)) {
+			if (is_out_of_date(line)) {
+			        (void) printf("1 ");
+			} else {
+			        (void) printf("0 ");
+			}
+		}
+		print_filename(target);
+	    	(void) printf(":\t");
+	    	print_deplist(line->body.line.dependencies);
+		print_rec_info(target);
+	   	(void) printf("\n");
+	 	for (dep = line->body.line.dependencies;
+		     dep != NULL;
+		     dep = dep->next) {
+			print_deps(dep->name,
+			           get_prop(dep->name->prop, line_prop));
+		}
+	}
+}
+
+static Boolean
+is_out_of_date(Property line)
+{
+	Dependency	dep;
+	Property	line2;
+
+	if (line == NULL) {
+		return false;
+	}
+	if (line->body.line.is_out_of_date) {
+		return true;
+	}
+	for (dep = line->body.line.dependencies;
+	     dep != NULL;
+	     dep = dep->next) {
+		line2 = get_prop(dep->name->prop, line_prop);
+		if (is_out_of_date(line2)) {
+			line->body.line.is_out_of_date = true;
+			return true;
+		}
+	}
+	return false;
+}
+
+/*
+ * Given a dependency print it and all its siblings.
+ */
+static void
+print_deplist(Dependency head)
+{
+	Dependency	dp;
+
+	for (dp = head; dp != NULL; dp = dp->next) {
+		if ((report_dependencies_level != 2) ||
+		    ((!dp->automatic) ||
+		     (dp->name->is_double_colon))) {
+			if (dp->name != force) {
+				putwchar(' ');
+				print_filename(dp->name);
+			}
+		}
+	}
+}
+
+/*
+ * Print the name of a file for the -P option.
+ * If the file is a directory put on a trailing slash.
+ */
+static void
+print_filename(Name name)
+{
+	(void) printf("%s", name->string_mb);
+/*
+	if (name->stat.is_dir) {
+		putwchar('/');
+	}
+ */
+}
+
+/*
+ *	should_print_dep(line)
+ *
+ *	Test if we should print the dependencies of this target.
+ *	The line must exist and either have children dependencies
+ *	or have a command that is not an SCCS command.
+ *
+ *	Return value:
+ *				true if the dependencies should be printed
+ *
+ *	Parameters:
+ *		line		We get the dependency list from here
+ *
+ *	Global variables used:
+ */
+static Boolean
+should_print_dep(Property line)
+{
+	if (line == NULL) {
+		return false;
+	}
+	if (line->body.line.dependencies != NULL) {
+		return true;
+	}
+#ifdef SUNOS4_AND_AFTER
+	if (line->body.line.sccs_command) {
+#else
+	if (is_true(line->body.line.sccs_command)) {
+#endif
+		return false;
+	}
+	return true;
+}
+
+/*
+ * Print out the root nodes of all the dependency trees
+ * in this makefile.
+ */
+static void
+print_forest(Name target)
+{
+	Name_set::iterator np, e;
+	Property	line;
+
+ 	for (np = hashtab.begin(), e = hashtab.end(); np != e; np++) {
+#ifdef SUNOS4_AND_AFTER
+			if (np->is_target && !np->has_parent && np != target) {
+#else
+			if (is_true(np->is_target) && 
+			    is_false(np->has_parent) &&
+			    np != target) {
+#endif
+				(void) doname_check(np, true, false, false);
+				line = get_prop(np->prop, line_prop);
+				printf("-\n");
+				print_deps(np, line);
+			}
+	}
+}
+
+#ifndef SUNOS4_AND_AFTER
+printdesc()
+{
+	Name_set::iterator	p, e;
+	register Property	prop;
+	register Dependency	dep;
+	register Cmd_line	rule;
+	Percent			percent, percent_depe;
+
+	/* Default target */
+	if (default_target_to_build != NULL) {
+		print_rule(default_target_to_build);
+		default_target_to_build->dependency_printed= true;
+	};
+	(void)printf("\n");
+
+	/* .AR_REPLACE */
+	if (ar_replace_rule != NULL) {
+		(void)printf("%s:\n", cached_names.ar_replace->string_mb);
+		for (rule= ar_replace_rule; rule != NULL; rule= rule->next)
+			(void)printf("\t%s\n", rule->command_line->string_mb);
+	};
+
+	/* .DEFAULT */
+	if (default_rule != NULL) {
+		(void)printf("%s:\n", cached_names.default_rule->string_mb);
+		for (rule= default_rule; rule != NULL; rule= rule->next)
+			(void)printf("\t%s\n", rule->command_line->string_mb);
+	};
+
+	/* .IGNORE */
+	if (is_true(flag.ignore_errors))
+		(void)printf("%s:\n", cached_names.ignore->string_mb);
+
+	/* .KEEP_STATE: */
+	if (is_true(flag.keep_state))
+		(void)printf("%s:\n\n", cached_names.dot_keep_state->string_mb);
+
+	/* .PRECIOUS */
+	(void)printf("%s: ", cached_names.precious->string_mb);
+ 	for (p = hashtab.begin(), e = hashtab.end(); p != e; p++)
+			if (is_true(p->stat.is_precious | all_precious))
+				(void)printf("%s ", p->string_mb);
+	(void)printf("\n");
+
+	/* .SCCS_GET */
+	if (sccs_get_rule != NULL) {
+		(void)printf("%s:\n", cached_names.sccs_get->string_mb);
+		for (rule= sccs_get_rule; rule != NULL; rule= rule->next)
+			(void)printf("\t%s\n", rule->command_line->string_mb);
+	};
+
+	/* .SILENT */
+	if (is_true(flag.silent))
+		(void)printf("%s:\n", cached_names.silent->string_mb);
+
+	/* .SUFFIXES: */
+	(void)printf("%s: ", cached_names.suffixes->string_mb);
+	for (dep= suffixes; dep != NULL; dep= dep->next) {
+		(void)printf("%s ", dep->name->string_mb);
+		build_suffix_list(dep->name);
+	};
+	(void)printf("\n\n");
+
+	/* % rules */
+	for (percent= percent_list; percent != NULL; percent= percent->next) {
+		(void) printf("%s:", percent->name->string_mb);
+
+		for (percent_depe= percent->dependencies; percent_depe != NULL; percent_depe = percent_depe->next)
+			(void) printf(" %s", percent_depe->name->string_mb);
+
+		(void) printf("\n");
+
+		for (rule= percent->command_template; rule != NULL; rule= rule->next)
+			(void)printf("\t%s\n", rule->command_line->string_mb);
+	};
+
+	/* Suffix rules */
+ 	for (p = hashtab.begin(), e = hashtab.end(); p != e; p++)
+			if (is_false(p->dependency_printed) && (p->string[0] == PERIOD)) {
+				print_rule(p);
+				p->dependency_printed= true;
+			};
+
+	/* Macro assignments */
+ 	for (p = hashtab.begin(), e = hashtab.end(); p != e; p++)
+			if (((prop= get_prop(p->prop, macro_prop)) != NULL) &&
+			    (prop->body.macro.value != NULL)) {
+				(void)printf("%s", p->string_mb);
+				print_value(prop->body.macro.value,
+					    prop->body.macro.daemon);
+			};
+	(void)printf("\n");
+
+	/* Delays */
+ 	for (p = hashtab.begin(), e = hashtab.end(); p != e; p++)
+			for (prop= get_prop(p->prop, conditional_prop);
+			     prop != NULL;
+			     prop= get_prop(prop->next, conditional_prop)) {
+				(void)printf("%s := %s",
+					     p->string_mb,
+					     prop->body.conditional.name->string_mb);
+				print_value(prop->body.conditional.value, no_daemon);
+			};
+	(void)printf("\n");
+
+	/* All other dependencies */
+ 	for (p = hashtab.begin(), e = hashtab.end(); p != e; p++)
+			if (is_false(p->dependency_printed) && (p->colons != no_colon))
+				print_rule(p);
+	(void)printf("\n");
+	exit(0);
+}
+#endif
+
+/*
+ *	This is a set  of routines for dumping the internal make state
+ *	Used for the -p option
+ */
+void
+print_value(register Name value, Daemon daemon)
+	             		      
+#ifdef SUNOS4_AND_AFTER
+              			       
+#else
+	           		       
+#endif
+{
+	Chain			cp;
+
+	if (value == NULL)
+		(void)printf("=\n");
+	else
+		switch (daemon) {
+		    case no_daemon:
+			(void)printf("= %s\n", value->string_mb);
+			break;
+		    case chain_daemon:
+			for (cp= (Chain) value; cp != NULL; cp= cp->next)
+				(void)printf(cp->next == NULL ? "%s" : "%s ",
+					cp->name->string_mb);
+			(void)printf("\n");
+			break;
+		};
+}
+
+static void
+print_rule(register Name target)
+{
+	register Cmd_line	rule;
+	register Property	line;
+
+	if (((line= get_prop(target->prop, line_prop)) == NULL) ||
+	    ((line->body.line.command_template == NULL) &&
+	     (line->body.line.dependencies == NULL)))
+		return;
+	print_dependencies(target, line);
+	for (rule= line->body.line.command_template; rule != NULL; rule= rule->next)
+		(void)printf("\t%s\n", rule->command_line->string_mb);
+}
+
+
+/* 
+ *  If target is recursive,  print the following to standard out:
+ *	.RECURSIVE subdir targ Makefile
+ */
+static void
+print_rec_info(Name target)
+{
+	Recursive_make	rp;
+	wchar_t		*colon;
+
+	report_recursive_init();
+
+	rp = find_recursive_target(target);
+
+	if (rp) {
+		/* 
+		 * if found,  print starting with the space after the ':'
+		 */
+		colon = (wchar_t *) wschr(rp->oldline, (int) colon_char);
+		(void) printf("%s", colon + 1);
+	}
+}
+		
--- /dev/null	2015-05-20 11:04:10.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/common/parallel.cc	2015-05-20 11:04:10.405300470 -0400
@@ -0,0 +1,2477 @@
+/*
+ * 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 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)parallel.cc 1.75 06/12/12
+ */
+
+#pragma	ident	"@(#)parallel.cc	1.75	06/12/12"
+
+#ifdef TEAMWARE_MAKE_CMN
+
+/*
+ *	parallel.cc
+ *
+ *	Deal with the parallel processing
+ */
+
+/*
+ * Included files
+ */
+#ifdef DISTRIBUTED
+#include <avo/strings.h>	/* AVO_STRDUP() */
+#include <dm/Avo_DoJobMsg.h>
+#include <dm/Avo_MToolJobResultMsg.h>
+#endif
+#include <errno.h>		/* errno */
+#include <fcntl.h>
+#include <avo/util.h>		/* avo_get_user(), avo_hostname() */
+#include <mk/defs.h>
+#include <mksh/dosys.h>		/* redirect_io() */
+#include <mksh/macro.h>		/* expand_value() */
+#include <mksh/misc.h>		/* getmem() */
+#include <sys/signal.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#ifdef SGE_SUPPORT
+#include <dmthread/Avo_PathNames.h>
+#endif
+
+
+/*
+ * Defined macros
+ */
+#define MAXRULES		100
+
+/*
+ * This const should be in avo_dms/include/AvoDmakeCommand.h
+ */
+const int local_host_mask = 0x20;
+
+
+/*
+ * typedefs & structs
+ */
+
+
+/*
+ * Static variables
+ */
+#ifdef TEAMWARE_MAKE_CMN
+static	Boolean		just_did_subtree = false;
+static	char		local_host[MAXNAMELEN] = "";
+static	char		user_name[MAXNAMELEN] = "";
+#endif
+static	int		pmake_max_jobs = 0;
+static	pid_t		process_running = -1;
+static	Running		*running_tail = &running_list;
+static	Name		subtree_conflict;
+static	Name		subtree_conflict2;
+
+
+/*
+ * File table of contents
+ */
+#ifdef DISTRIBUTED
+static	void		append_dmake_cmd(Avo_DoJobMsg *dmake_job_msg, char *orig_cmd_line, int cmd_options);
+static	void		append_job_result_msg(Avo_MToolJobResultMsg *msg, char *outFn, char *errFn);
+static	void		send_job_result_msg(Running rp);
+#endif
+static	void		delete_running_struct(Running rp);
+static	Boolean		dependency_conflict(Name target);
+static	Doname		distribute_process(char **commands, Property line);
+static	void		doname_subtree(Name target, Boolean do_get, Boolean implicit);
+static	void		dump_out_file(char *filename, Boolean err);
+static	void		finish_doname(Running rp);
+static	void		maybe_reread_make_state(void);
+static	void		process_next(void);
+static	void		reset_conditionals(int cnt, Name *targets, Property *locals);
+static	pid_t           run_rule_commands(char *host, char **commands);
+static	Property	*set_conditionals(int cnt, Name *targets);
+static	void		store_conditionals(Running rp);
+
+
+/*
+ *	execute_parallel(line, waitflg)
+ *
+ *	DMake 2.x:
+ *	parallel mode: spawns a parallel process to execute the command group.
+ *	distributed mode: sends the command group down the pipe to rxm.
+ *
+ *	Return value:
+ *				The result of the execution
+ *
+ *	Parameters:
+ *		line		The command group to execute
+ */
+Doname
+execute_parallel(Property line, Boolean waitflg, Boolean local)
+{
+	int			argcnt;
+	int			cmd_options = 0;
+	char			*commands[MAXRULES + 5];
+	char			*cp;
+#ifdef DISTRIBUTED
+	Avo_DoJobMsg		*dmake_job_msg = NULL;
+#endif
+	Name			dmake_name;
+	Name			dmake_value;
+	int			ignore;
+	Name			make_machines_name;
+	char			**p;
+	Property		prop;
+	Doname			result = build_ok;
+	Cmd_line		rule;
+	Boolean			silent_flag;
+	Name			target = line->body.line.target;
+	Boolean			wrote_state_file = false;
+
+	if ((pmake_max_jobs == 0) &&
+	    (dmake_mode_type == parallel_mode)) {
+		if (user_name[0] == '\0') {
+			avo_get_user(user_name, NULL);
+		}
+		if (local_host[0] == '\0') {
+			strcpy(local_host, avo_hostname());
+		}
+		MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MAX_JOBS"));
+		dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
+		if (((prop = get_prop(dmake_name->prop, macro_prop)) != NULL) &&
+		    ((dmake_value = prop->body.macro.value) != NULL)) {
+			pmake_max_jobs = atoi(dmake_value->string_mb);
+			if (pmake_max_jobs <= 0) {
+				warning(catgets(catd, 1, 308, "DMAKE_MAX_JOBS cannot be less than or equal to zero."));
+				warning(catgets(catd, 1, 309, "setting DMAKE_MAX_JOBS to %d."), PMAKE_DEF_MAX_JOBS);
+				pmake_max_jobs = PMAKE_DEF_MAX_JOBS;
+			}
+		} else {
+			/*
+			 * For backwards compatibility w/ PMake 1.x, when
+			 * DMake 2.x is being run in parallel mode, DMake
+			 * should parse the PMake startup file
+			 * $(HOME)/.make.machines to get the pmake_max_jobs.
+			 */
+			MBSTOWCS(wcs_buffer, NOCATGETS("PMAKE_MACHINESFILE"));
+			dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
+			if (((prop = get_prop(dmake_name->prop, macro_prop)) != NULL) &&
+			    ((dmake_value = prop->body.macro.value) != NULL)) {
+				make_machines_name = dmake_value;
+			} else {
+				make_machines_name = NULL;
+			}
+			if ((pmake_max_jobs = read_make_machines(make_machines_name)) <= 0) {
+				pmake_max_jobs = PMAKE_DEF_MAX_JOBS;
+			}
+		}
+#ifdef DISTRIBUTED
+		if (send_mtool_msgs) {
+			send_rsrc_info_msg(pmake_max_jobs, local_host, user_name);
+		}
+#endif
+	}
+
+	if ((dmake_mode_type == serial_mode) ||
+	    ((dmake_mode_type == parallel_mode) && (waitflg))) {
+		return (execute_serial(line));
+	}
+
+#ifdef DISTRIBUTED
+	if (dmake_mode_type == distributed_mode) {
+		if(local) {
+//			return (execute_serial(line));
+			waitflg = true;
+		}
+		dmake_job_msg = new Avo_DoJobMsg();
+		dmake_job_msg->setJobId(++job_msg_id);
+		dmake_job_msg->setTarget(target->string_mb);
+		dmake_job_msg->setImmediateOutput(0);
+		called_make = false;
+	} else
+#endif
+	{
+		p = commands;
+	}
+
+	argcnt = 0;
+	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);
+		}
+		if (dmake_mode_type == distributed_mode) {
+			cmd_options = 0;
+			if(local) {
+				cmd_options |= local_host_mask;
+			}
+		} else {
+			silent_flag = false;
+			ignore = 0;
+		}
+		if (rule->command_line->hash.length > 0) {
+			if (++argcnt == MAXRULES) {
+				if (dmake_mode_type == distributed_mode) {
+					/* XXX - tell rxm to execute on local host. */
+					/* I WAS HERE!!! */
+				} else {
+					/* Too many rules, run serially instead. */
+					return build_serial;
+				}
+			}
+#ifdef DISTRIBUTED
+			if (dmake_mode_type == distributed_mode) {
+				/*
+				 * XXX - set assign_mask to tell rxm
+				 * to do the following.
+				 */
+/* From execute_serial():
+				if (rule->assign) {
+					result = build_ok;
+					do_assign(rule->command_line, target);
+ */
+				if (0) {
+				} else if (report_dependencies_level == 0) {
+					if (rule->ignore_error) {
+						cmd_options |= ignore_mask;
+					}
+					if (rule->silent) {
+						cmd_options |= silent_mask;
+					}
+					if (rule->command_line->meta) {
+						cmd_options |= meta_mask;
+					}
+					if (rule->make_refd) {
+						cmd_options |= make_refd_mask;
+					}
+					if (do_not_exec_rule) {
+						cmd_options |= do_not_exec_mask;
+					}
+					append_dmake_cmd(dmake_job_msg,
+					                 rule->command_line->string_mb,
+					                 cmd_options);
+					/* Copying dosys()... */
+					if (rule->make_refd) {
+						if (waitflg) {
+							dmake_job_msg->setImmediateOutput(1);
+						}
+						called_make = true;
+						if (command_changed &&
+						    !wrote_state_file) {
+							write_state_file(0, false);
+							wrote_state_file = true;
+						}
+					}
+				}
+			} else
+#endif
+			{
+				if (rule->silent && !silent) {
+					silent_flag = true;
+				}
+				if (rule->ignore_error) {
+					ignore++;
+				}
+				/* XXX - need to add support for + prefix */
+				if (silent_flag || ignore) {
+					*p = getmem((silent_flag ? 1 : 0) +
+						    ignore +
+						    (strlen(rule->
+						           command_line->
+						           string_mb)) +
+						    1);
+					cp = *p++;
+					if (silent_flag) {
+						*cp++ = (int) at_char;
+					}
+					if (ignore) {
+						*cp++ = (int) hyphen_char;
+					}
+					(void) strcpy(cp, rule->command_line->string_mb);
+				} else {
+					*p++ = rule->command_line->string_mb;
+				}
+			}
+		}
+	}
+	if ((argcnt == 0) ||
+	    (report_dependencies_level > 0)) {
+#ifdef DISTRIBUTED
+		if (dmake_job_msg) {
+			delete dmake_job_msg;
+		}
+#endif
+		return build_ok;
+	}
+#ifdef DISTRIBUTED
+	if (dmake_mode_type == distributed_mode) {
+		// Send  a DoJob message to the rxm process.
+		distribute_rxm(dmake_job_msg);
+
+		// Wait for an acknowledgement.
+		Avo_AcknowledgeMsg *ackMsg = getAcknowledgeMsg();
+		if (ackMsg) {
+			delete ackMsg;
+		}
+
+		if (waitflg) {
+			// Wait for, and process a job result.
+			result = await_dist(waitflg);
+			if (called_make) {
+				maybe_reread_make_state();
+			}
+			check_state(temp_file_name);
+			if (result == build_failed) {
+				if (!continue_after_error) {
+
+#ifdef PRINT_EXIT_STATUS
+					warning(NOCATGETS("I'm in execute_parallel. await_dist() returned build_failed"));
+#endif
+
+					fatal(catgets(catd, 1, 252, "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;
+			}
+			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) {
+					retmem_mb(val);
+					spro->body.env_mem.value = NULL;
+				}
+			}
+			return result;
+		} else {
+			parallel_process_cnt++;
+			return build_running;
+		}
+	} else
+#endif
+	{
+		*p = NULL;
+
+		Doname res = distribute_process(commands, line);
+		if (res == build_running) {
+			parallel_process_cnt++;
+		}
+
+		/*
+		 * Return only those memory that were specially allocated
+		 * for part of commands.
+		 */
+		for (int i = 0; commands[i] != NULL; i++) {
+			if ((commands[i][0] == (int) at_char) ||
+			    (commands[i][0] == (int) hyphen_char)) {
+				retmem_mb(commands[i]);
+			}
+		}
+		return res;
+	}
+}
+
+#ifdef DISTRIBUTED
+/*
+ *	append_dmake_cmd()
+ *
+ *	Replaces all escaped newline's (\<cr>)
+ *	  in the original command line with space's,
+ *	  then append the new command line to the DoJobMsg object.
+ */
+static void
+append_dmake_cmd(Avo_DoJobMsg *dmake_job_msg,
+                 char *orig_cmd_line,
+                 int cmd_options)
+{
+/*
+	Avo_DmakeCommand	*tmp_dmake_command;
+
+	tmp_dmake_command = new Avo_DmakeCommand(orig_cmd_line, cmd_options);
+	dmake_job_msg->appendCmd(tmp_dmake_command);
+	delete tmp_dmake_command;
+ */
+	dmake_job_msg->appendCmd(new Avo_DmakeCommand(orig_cmd_line, cmd_options));
+}
+#endif
+
+#ifdef TEAMWARE_MAKE_CMN
+#define MAXJOBS_ADJUST_RFE4694000
+
+#ifdef MAXJOBS_ADJUST_RFE4694000
+
+#include <unistd.h>	/* sysconf(_SC_NPROCESSORS_ONLN) */
+#include <sys/ipc.h>		/* ftok() */
+#include <sys/shm.h>		/* shmget(), shmat(), shmdt(), shmctl() */
+#include <semaphore.h>		/* sem_init(), sem_trywait(), sem_post(), sem_destroy() */
+#if defined(linux)
+#define	LOADAVG_1MIN	0
+#else
+#include <sys/loadavg.h>	/* getloadavg() */
+#endif /* linux */
+
+/*
+ *	adjust_pmake_max_jobs (int pmake_max_jobs)
+ *
+ *	Parameters:
+ * 		pmake_max_jobs	- max jobs limit set by user
+ *
+ *	External functions used:
+ *		sysconf()
+ * 		getloadavg()
+ */
+static int
+adjust_pmake_max_jobs (int pmake_max_jobs)
+{
+	static int	ncpu = 0;
+	double		loadavg[3];
+	int		adjustment;
+	int		adjusted_max_jobs;
+
+	if (ncpu <= 0) {
+		if ((ncpu = sysconf(_SC_NPROCESSORS_ONLN)) <= 0) {
+			ncpu = 1;
+		}
+	}
+	if (getloadavg(loadavg, 3) != 3) return(pmake_max_jobs);
+	adjustment = ((int)loadavg[LOADAVG_1MIN]);
+	if (adjustment < 2) return(pmake_max_jobs);
+	if (ncpu > 1) {
+		adjustment = adjustment / ncpu;
+	}
+	adjusted_max_jobs = pmake_max_jobs - adjustment;
+	if (adjusted_max_jobs < 1) adjusted_max_jobs = 1;
+	return(adjusted_max_jobs);
+}
+
+/*
+ *  M2 adjust mode data and functions
+ *
+ *  m2_init()		- initializes M2 shared semaphore
+ *  m2_acquire_job()	- decrements M2 semaphore counter
+ *  m2_release_job()	- increments M2 semaphore counter
+ *  m2_fini()		- destroys M2 semaphore and shared memory*
+ *
+ *  Environment variables:
+ *	__DMAKE_M2_FILE__
+ *
+ *  External functions:
+ *	ftok(), shmget(), shmat(), shmdt(), shmctl()
+ *	sem_init(), sem_trywait(), sem_post(), sem_destroy()
+ *	creat(), close(), unlink()
+ *	getenv(), putenv()
+ *
+ *  Static variables:
+ *	m2_file		- tmp file name to create ipc key for shared memory
+ *	m2_shm_id	- shared memory id
+ *	m2_shm_sem	- shared memory semaphore
+ */
+
+static char	m2_file[MAXPATHLEN];
+static int	m2_shm_id = -1;
+static sem_t*	m2_shm_sem = 0;
+
+static int
+m2_init() {
+	char	*var;
+	key_t	key;
+
+	if ((var = getenv(NOCATGETS("__DMAKE_M2_FILE__"))) == 0) {
+		/* compose tmp file name */
+		sprintf(m2_file, NOCATGETS("%s/dmake.m2.%d.XXXXXX"), tmpdir, getpid());
+
+		/* create tmp file */
+		int fd = mkstemp(m2_file);
+		if (fd < 0) {
+			return -1;
+		} else {
+			close(fd);
+		}
+	} else {
+		/* using existing semaphore */
+		strcpy(m2_file, var);
+	}
+
+	/* combine IPC key */
+	if ((key = ftok(m2_file, 38)) == (key_t) -1) {
+		return -1;
+	}
+
+	/* create shared memory */
+	if ((m2_shm_id = shmget(key, sizeof(*m2_shm_sem), 0666 | (var ? 0 : IPC_CREAT|IPC_EXCL))) == -1) {
+		return -1;
+	}
+
+	/* attach shared memory */
+	if ((m2_shm_sem = (sem_t*) shmat(m2_shm_id, 0, 0666)) == (sem_t*)-1) {
+		return -1;
+	}
+
+	/* root process */
+	if (var == 0) {
+		/* initialize semaphore */
+		if (sem_init(m2_shm_sem, 1, pmake_max_jobs)) {
+			return -1;
+		}
+
+		/* alloc memory for env variable */
+		if ((var = (char*) malloc(MAXPATHLEN)) == 0) {
+			return -1;
+		}
+
+		/* put key to env */
+		sprintf(var, NOCATGETS("__DMAKE_M2_FILE__=%s"), m2_file);
+		if (putenv(var)) {
+			return -1;
+		}
+	}
+	return 0;
+}
+
+static void
+m2_fini() {
+	if (m2_shm_id >= 0) {
+		struct shmid_ds stat;
+
+		/* determine the number of attached processes */
+		if (shmctl(m2_shm_id, IPC_STAT, &stat) == 0) {
+			if (stat.shm_nattch <= 1) {
+				/* destroy semaphore */
+				if (m2_shm_sem != 0) {
+					(void) sem_destroy(m2_shm_sem);
+				}
+
+				/* destroy shared memory */
+				(void) shmctl(m2_shm_id, IPC_RMID, &stat);
+
+				/* remove tmp file created for the key */
+				(void) unlink(m2_file);
+			} else {
+				/* detach shared memory */
+				if (m2_shm_sem != 0) {
+					(void) shmdt((char*) m2_shm_sem);
+				}
+			}
+		}
+
+		m2_shm_id = -1;
+		m2_shm_sem = 0;
+	}
+}
+
+static int
+m2_acquire_job() {
+	if ((m2_shm_id >= 0) && (m2_shm_sem != 0)) {
+		if (sem_trywait(m2_shm_sem) == 0) {
+			return 1;
+		}
+		if (errno == EAGAIN) {
+			return 0;
+		}
+	}
+	return -1;
+}
+
+static int
+m2_release_job() {
+	if ((m2_shm_id >= 0) && (m2_shm_sem != 0)) {
+		if (sem_post(m2_shm_sem) == 0) {
+			return 0;
+		}
+	}
+	return -1;
+}
+
+/*
+ *  job adjust mode
+ *
+ *  Possible values:
+ *    ADJUST_M1		- adjustment by system load (default)
+ *    ADJUST_M2		- fixed limit of jobs for the group of nested dmakes
+ *    ADJUST_NONE	- no adjustment - fixed limit of jobs for the current dmake
+ */
+static enum {
+	ADJUST_UNKNOWN,
+	ADJUST_M1,
+	ADJUST_M2,
+	ADJUST_NONE
+} job_adjust_mode = ADJUST_UNKNOWN;
+
+/*
+ *  void job_adjust_fini()
+ *
+ *  Description:
+ *	Cleans up job adjust data.
+ *
+ *  Static variables:
+ *	job_adjust_mode	Current job adjust mode
+ */
+void
+job_adjust_fini() {
+	if (job_adjust_mode == ADJUST_M2) {
+		m2_fini();
+	}
+}
+
+/*
+ *  void job_adjust_error()
+ *
+ *  Description:
+ *	Prints warning message, cleans up job adjust data, and disables job adjustment
+ *
+ *  Environment:
+ *	DMAKE_ADJUST_MAX_JOBS
+ *
+ *  External functions:
+ *	putenv()
+ *
+ *  Static variables:
+ *	job_adjust_mode	Current job adjust mode
+ */
+static void
+job_adjust_error() {
+	if (job_adjust_mode != ADJUST_NONE) {
+		/* cleanup internals */
+		job_adjust_fini();
+
+		/* warning message for the user */
+		warning(catgets(catd, 1, 339, "Encountered max jobs auto adjustment error - disabling auto adjustment."));
+
+		/* switch off job adjustment for the children */
+		putenv(NOCATGETS("DMAKE_ADJUST_MAX_JOBS=NO"));
+
+		/* and for this dmake */
+		job_adjust_mode = ADJUST_NONE;
+	}
+}
+
+/*
+ *  void job_adjust_init()
+ *
+ *  Description:
+ *	Parses DMAKE_ADJUST_MAX_JOBS env variable
+ *	and performs appropriate initializations.
+ *
+ *  Environment:
+ *	DMAKE_ADJUST_MAX_JOBS
+ *	  DMAKE_ADJUST_MAX_JOBS == "NO"	- no adjustment
+ *	  DMAKE_ADJUST_MAX_JOBS == "M2"	- M2 adjust mode
+ *	  other				- M1 adjust mode
+ *
+ *  External functions:
+ *	getenv()
+ *
+ *  Static variables:
+ *	job_adjust_mode	Current job adjust mode
+ */
+static void
+job_adjust_init() {
+	if (job_adjust_mode == ADJUST_UNKNOWN) {
+		/* default mode */
+		job_adjust_mode = ADJUST_M1;
+
+		/* determine adjust mode */
+		if (char *var = getenv(NOCATGETS("DMAKE_ADJUST_MAX_JOBS"))) {
+			if (strcasecmp(var, NOCATGETS("NO")) == 0) {
+				job_adjust_mode = ADJUST_NONE;
+			} else if (strcasecmp(var, NOCATGETS("M2")) == 0) {
+				job_adjust_mode = ADJUST_M2;
+			}
+		}
+
+		/* M2 specific initialization */
+		if (job_adjust_mode == ADJUST_M2) {
+			if (m2_init()) {
+				job_adjust_error();
+			}
+		}
+	}
+}
+
+#endif /* MAXJOBS_ADJUST_RFE4694000 */
+#endif /* TEAMWARE_MAKE_CMN */
+
+/*
+ *	distribute_process(char **commands, Property line)
+ *
+ *	Parameters:
+ *		commands	argv vector of commands to execute
+ *
+ *	Return value:
+ *				The result of the execution
+ *
+ *	Static variables used:
+ *		process_running	Set to the pid of the process set running
+ * #if defined (TEAMWARE_MAKE_CMN) && defined (MAXJOBS_ADJUST_RFE4694000)
+ *		job_adjust_mode	Current job adjust mode
+ * #endif
+ */
+static Doname
+distribute_process(char **commands, Property line)
+{
+	static unsigned	file_number = 0;
+	wchar_t		string[MAXPATHLEN];
+	char		mbstring[MAXPATHLEN];
+	int		filed;
+	int		res;
+	int		tmp_index;
+	char		*tmp_index_str_ptr;
+
+#if !defined (TEAMWARE_MAKE_CMN) || !defined (MAXJOBS_ADJUST_RFE4694000)
+	while (parallel_process_cnt >= pmake_max_jobs) {
+		await_parallel(false);
+		finish_children(true);
+	}
+#else /* TEAMWARE_MAKE_CMN && MAXJOBS_ADJUST_RFE4694000 */
+	/* initialize adjust mode, if not initialized */
+	if (job_adjust_mode == ADJUST_UNKNOWN) {
+		job_adjust_init();
+	}
+
+	/* actions depend on adjust mode */
+	switch (job_adjust_mode) {
+	case ADJUST_M1:
+		while (parallel_process_cnt >= adjust_pmake_max_jobs (pmake_max_jobs)) {
+			await_parallel(false);
+			finish_children(true);
+		}
+		break;
+	case ADJUST_M2:
+		if ((res = m2_acquire_job()) == 0) {
+			if (parallel_process_cnt > 0) {
+				await_parallel(false);
+				finish_children(true);
+
+				if ((res = m2_acquire_job()) == 0) {
+					return build_serial;
+				}
+			} else {
+				return build_serial;
+			}
+		}
+		if (res < 0) {
+			/* job adjustment error */
+			job_adjust_error();
+
+			/* no adjustment */
+			while (parallel_process_cnt >= pmake_max_jobs) {
+				await_parallel(false);
+				finish_children(true);
+			}
+		}
+		break;
+	default:
+		while (parallel_process_cnt >= pmake_max_jobs) {
+			await_parallel(false);
+			finish_children(true);
+		}
+	}
+#endif /* TEAMWARE_MAKE_CMN && MAXJOBS_ADJUST_RFE4694000 */
+#ifdef DISTRIBUTED
+	if (send_mtool_msgs) {
+		send_job_start_msg(line);
+	}
+#endif
+#ifdef DISTRIBUTED
+	setvar_envvar((Avo_DoJobMsg *)NULL);
+#else
+	setvar_envvar();
+#endif
+	/*
+	 * Tell the user what DMake is doing.
+	 */
+	if (!silent && output_mode != txt2_mode) {
+		/*
+		 * Print local_host --> x job(s).
+		 */
+		(void) fprintf(stdout,
+		               catgets(catd, 1, 325, "%s --> %d %s\n"),
+		               local_host,
+		               parallel_process_cnt + 1,
+		               (parallel_process_cnt == 0) ? catgets(catd, 1, 124, "job") : catgets(catd, 1, 125, "jobs"));
+
+		/* Print command line(s). */
+		tmp_index = 0;
+		while (commands[tmp_index] != NULL) {
+		    /* No @ char. */
+		    /* XXX - need to add [2] when + prefix is added */
+		    if ((commands[tmp_index][0] != (int) at_char) &&
+		        (commands[tmp_index][1] != (int) at_char)) {
+			tmp_index_str_ptr = commands[tmp_index];
+			if (*tmp_index_str_ptr == (int) hyphen_char) {
+				tmp_index_str_ptr++;
+			}
+                        (void) fprintf(stdout, "%s\n", tmp_index_str_ptr);
+		    }
+		    tmp_index++;
+		}
+		(void) fflush(stdout);
+	}
+
+	(void) sprintf(mbstring,
+		        NOCATGETS("%s/dmake.stdout.%d.%d.XXXXXX"),
+			tmpdir,
+		        getpid(),
+	                file_number++);
+
+	mktemp(mbstring);
+
+	stdout_file = strdup(mbstring);
+	stderr_file = NULL;
+#if defined (TEAMWARE_MAKE_CMN) && defined(REDIRECT_ERR)
+	if (!out_err_same) {
+		(void) sprintf(mbstring,
+			        NOCATGETS("%s/dmake.stderr.%d.%d.XXXXXX"),
+				tmpdir,
+			        getpid(),
+		                file_number++);
+
+		mktemp(mbstring);
+
+		stderr_file = strdup(mbstring);
+	}
+#endif
+
+#ifdef SGE_SUPPORT
+	if (grid) {
+		static char *dir4gridscripts = NULL;
+		static char *hostName = NULL;
+		if (dir4gridscripts == NULL) {
+			Name		dmakeOdir_name, dmakeOdir_value;
+			Property	prop;
+			MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_ODIR"));
+			dmakeOdir_name = GETNAME(wcs_buffer, FIND_LENGTH);
+			if (((prop = get_prop(dmakeOdir_name->prop, macro_prop)) != NULL) &&
+			    ((dmakeOdir_value = prop->body.macro.value) != NULL)) {
+				dir4gridscripts = dmakeOdir_value->string_mb;
+			}
+			dir4gridscripts = Avo_PathNames::pathname_output_directory(dir4gridscripts);
+			hostName = Avo_PathNames::pathname_local_host();
+		}
+		(void) sprintf(script_file,
+		        	NOCATGETS("%s/dmake.script.%s.%d.%d.XXXXXX"),
+				dir4gridscripts,
+				hostName,
+			        getpid(),
+		                file_number++);
+	}
+#endif /* SGE_SUPPORT */
+	process_running = run_rule_commands(local_host, commands);
+
+	return build_running;
+}
+
+/*
+ *	doname_parallel(target, do_get, implicit)
+ *
+ *	Processes the given target and finishes up any parallel
+ *	processes left running.
+ *
+ *	Return value:
+ *				Result of target build
+ *
+ *	Parameters:
+ *		target		Target to build
+ *		do_get		True if sccs get to be done
+ *		implicit	True if this is an implicit target
+ */
+Doname
+doname_parallel(Name target, Boolean do_get, Boolean implicit)
+{
+	Doname		result;
+
+	result = doname_check(target, do_get, implicit, false);
+	if (result == build_ok || result == build_failed) {
+		return result;
+	}
+	finish_running();
+	return (Doname) target->state;
+}
+
+/*
+ *	doname_subtree(target, do_get, implicit)
+ *
+ *	Completely computes an object and its dependents for a
+ *	serial subtree build.
+ *
+ *	Parameters:
+ *		target		Target to build
+ *		do_get		True if sccs get to be done
+ *		implicit	True if this is an implicit target
+ *
+ *	Static variables used:
+ *		running_tail	Tail of the list of running processes
+ *
+ *	Global variables used:
+ *		running_list	The list of running processes
+ */
+static void
+doname_subtree(Name target, Boolean do_get, Boolean implicit)
+{
+	Running		save_running_list;
+	Running		*save_running_tail;
+
+	save_running_list = running_list;
+	save_running_tail = running_tail;
+	running_list = NULL;
+	running_tail = &running_list;
+	target->state = build_subtree;
+	target->checking_subtree = true;
+	while(doname_check(target, do_get, implicit, false) == build_running) {
+		target->checking_subtree = false;
+		finish_running();
+		target->state = build_subtree;
+	}
+	target->checking_subtree = false;
+	running_list = save_running_list;
+	running_tail = save_running_tail;
+}
+
+/*
+ *	finish_running()
+ *
+ *	Keeps processing until the running_list is emptied out.
+ *
+ *	Parameters:
+ *
+ *	Global variables used:
+ *		running_list	The list of running processes
+ */
+void
+finish_running(void)
+{
+	while (running_list != NULL) {
+#ifdef DISTRIBUTED
+		if (dmake_mode_type == distributed_mode) {
+			if ((just_did_subtree) ||
+			    (parallel_process_cnt == 0)) {
+				just_did_subtree = false;
+			} else {
+				(void) await_dist(false);
+				finish_children(true);
+			}
+		} else
+#endif
+		{
+			await_parallel(false);
+			finish_children(true);
+		}
+		if (running_list != NULL) {
+			process_next();
+		}
+	}
+}
+
+/*
+ *	process_next()
+ *
+ *	Searches the running list for any targets which can start processing.
+ *	This can be a pending target, a serial target, or a subtree target.
+ *
+ *	Parameters:
+ *
+ *	Static variables used:
+ *		running_tail		The end of the list of running procs
+ *		subtree_conflict	A target which conflicts with a subtree
+ *		subtree_conflict2	The other target which conflicts
+ *
+ *	Global variables used:
+ *		commands_done		True if commands executed
+ *		debug_level		Controls debug output
+ *		parallel_process_cnt	Number of parallel process running
+ *		recursion_level		Indentation for debug output
+ *		running_list		List of running processes
+ */
+static void
+process_next(void)
+{
+	Running		rp;
+	Running		*rp_prev;
+	Property	line;
+	Chain		target_group;
+	Dependency	dep;
+	Boolean		quiescent = true;
+	Running		*subtree_target;
+	Boolean		saved_commands_done;
+	Property	*conditionals;
+
+	subtree_target = NULL;
+	subtree_conflict = NULL;
+	subtree_conflict2 = NULL;
+	/*
+	 * If nothing currently running, build a serial target, if any.
+	 */
+start_loop_1:
+	for (rp_prev = &running_list, rp = running_list;
+	     rp != NULL && parallel_process_cnt == 0;
+	     rp = rp->next) {
+		if (rp->state == build_serial) {
+			*rp_prev = rp->next;
+			if (rp->next == NULL) {
+				running_tail = rp_prev;
+			}
+			recursion_level = rp->recursion_level;
+			rp->target->state = build_pending;
+			(void) doname_check(rp->target,
+					    rp->do_get,
+					    rp->implicit,
+					    false);
+			quiescent = false;
+			delete_running_struct(rp);
+			goto start_loop_1;
+		} else {
+			rp_prev = &rp->next;
+		}
+	}
+	/*
+	 * Find a target to build.  The target must be pending, have all
+	 * its dependencies built, and not be in a target group with a target
+	 * currently building.
+	 */
+start_loop_2:
+	for (rp_prev = &running_list, rp = running_list;
+	     rp != NULL;
+	     rp = rp->next) {
+		if (!(rp->state == build_pending ||
+		      rp->state == build_subtree)) {
+			quiescent = false;
+			rp_prev = &rp->next;
+		} else if (rp->state == build_pending) {
+			line = get_prop(rp->target->prop, line_prop);
+			for (dep = line->body.line.dependencies;
+			     dep != NULL;
+			     dep = dep->next) {
+				if (dep->name->state == build_running ||
+				    dep->name->state == build_pending ||
+				    dep->name->state == build_serial) {
+					break;
+				}
+			}
+			if (dep == NULL) {
+				for (target_group = line->body.line.target_group;
+				     target_group != NULL;
+				     target_group = target_group->next) {
+					if (is_running(target_group->name)) {
+						break;
+					}
+				}
+				if (target_group == NULL) {
+					*rp_prev = rp->next;
+					if (rp->next == NULL) {
+						running_tail = rp_prev;
+					}
+					recursion_level = rp->recursion_level;
+					rp->target->state = rp->redo ?
+					  build_dont_know : build_pending;
+					saved_commands_done = commands_done;
+					conditionals =
+						set_conditionals
+						    (rp->conditional_cnt,
+						     rp->conditional_targets);
+					rp->target->dont_activate_cond_values = true;
+					if ((doname_check(rp->target,
+							  rp->do_get,
+							  rp->implicit,
+							  rp->target->has_target_prop ? true : false) !=
+					     build_running) &&
+					    !commands_done) {
+						commands_done =
+						  saved_commands_done;
+					}
+					rp->target->dont_activate_cond_values = false;
+					reset_conditionals
+						(rp->conditional_cnt,
+						 rp->conditional_targets,
+						 conditionals);
+					quiescent = false;
+					delete_running_struct(rp);
+					goto start_loop_2;
+				} else {
+					rp_prev = &rp->next;
+				}
+			} else {
+				rp_prev = &rp->next;
+			}
+		} else {
+			rp_prev = &rp->next;
+		}
+	}
+	/*
+	 * If nothing has been found to build and there exists a subtree
+	 * target with no dependency conflicts, build it.
+	 */
+	if (quiescent) {
+start_loop_3:
+		for (rp_prev = &running_list, rp = running_list;
+		     rp != NULL;
+		     rp = rp->next) {
+			if (rp->state == build_subtree) {
+				if (!dependency_conflict(rp->target)) {
+					*rp_prev = rp->next;
+					if (rp->next == NULL) {
+						running_tail = rp_prev;
+					}
+					recursion_level = rp->recursion_level;
+					doname_subtree(rp->target,
+						       rp->do_get,
+						       rp->implicit);
+#ifdef DISTRIBUTED
+					just_did_subtree = true;
+#endif
+					quiescent = false;
+					delete_running_struct(rp);
+					goto start_loop_3;
+				} else {
+					subtree_target = rp_prev;
+					rp_prev = &rp->next;
+				}
+			} else {
+				rp_prev = &rp->next;
+			}
+		}
+	}
+	/*
+	 * If still nothing found to build, we either have a deadlock
+	 * or a subtree with a dependency conflict with something waiting
+	 * to build.
+	 */
+	if (quiescent) {
+		if (subtree_target == NULL) {
+			fatal(catgets(catd, 1, 126, "Internal error: deadlock detected in process_next"));
+		} else {
+			rp = *subtree_target;
+			if (debug_level > 0) {
+				warning(catgets(catd, 1, 127, "Conditional macro conflict encountered for %s between %s and %s"),
+					subtree_conflict2->string_mb,
+					rp->target->string_mb,
+					subtree_conflict->string_mb);
+			}
+			*subtree_target = (*subtree_target)->next;
+			if (rp->next == NULL) {
+				running_tail = subtree_target;
+			}
+			recursion_level = rp->recursion_level;
+			doname_subtree(rp->target, rp->do_get, rp->implicit);
+#ifdef DISTRIBUTED
+			just_did_subtree = true;
+#endif
+			delete_running_struct(rp);
+		}
+	}
+}
+
+/*
+ *	set_conditionals(cnt, targets)
+ *
+ *	Sets the conditional macros for the targets given in the array of
+ *	targets.  The old macro values are returned in an array of
+ *	Properties for later resetting.
+ *
+ *	Return value:
+ *					Array of conditional macro settings
+ *
+ *	Parameters:
+ *		cnt			Number of targets
+ *		targets			Array of targets
+ */
+static Property *
+set_conditionals(int cnt, Name *targets)
+{
+	Property	*locals, *lp;
+	Name		*tp;
+
+	locals = (Property *) getmem(cnt * sizeof(Property));
+	for (lp = locals, tp = targets;
+	     cnt > 0;
+	     cnt--, lp++, tp++) {
+		*lp = (Property) getmem((*tp)->conditional_cnt *
+					sizeof(struct _Property));
+		set_locals(*tp, *lp);
+	}
+	return locals;
+}
+
+/*
+ *	reset_conditionals(cnt, targets, locals)
+ *
+ *	Resets the conditional macros as saved in the given array of
+ *	Properties.  The resets are done in reverse order.  Afterwards the
+ *	data structures are freed.
+ *
+ *	Parameters:
+ *		cnt			Number of targets
+ *		targets			Array of targets
+ *		locals			Array of dependency macro settings
+ */
+static void
+reset_conditionals(int cnt, Name *targets, Property *locals)
+{
+	Name		*tp;
+	Property	*lp;
+
+	for (tp = targets + (cnt - 1), lp = locals + (cnt - 1);
+	     cnt > 0;
+	     cnt--, tp--, lp--) {
+		reset_locals(*tp,
+			     *lp,
+			     get_prop((*tp)->prop, conditional_prop),
+			     0);
+		retmem_mb((caddr_t) *lp);
+	}
+	retmem_mb((caddr_t) locals);
+}
+
+/*
+ *	dependency_conflict(target)
+ *
+ *	Returns true if there is an intersection between
+ *	the subtree of the target and any dependents of the pending targets.
+ *
+ *	Return value:
+ *					True if conflict found
+ *
+ *	Parameters:
+ *		target			Subtree target to check
+ *
+ *	Static variables used:
+ *		subtree_conflict	Target conflict found
+ *		subtree_conflict2	Second conflict found
+ *
+ *	Global variables used:
+ *		running_list		List of running processes
+ *		wait_name		.WAIT, not a real dependency
+ */
+static Boolean
+dependency_conflict(Name target)
+{
+	Property	line;
+	Property	pending_line;
+	Dependency	dp;
+	Dependency	pending_dp;
+	Running		rp;
+
+	/* Return if we are already checking this target */
+	if (target->checking_subtree) {
+		return false;
+	}
+	target->checking_subtree = true;
+	line = get_prop(target->prop, line_prop);
+	if (line == NULL) {
+		target->checking_subtree = false;
+		return false;
+	}
+	/* Check each dependency of the target for conflicts */
+	for (dp = line->body.line.dependencies; dp != NULL; dp = dp->next) {
+		/* Ignore .WAIT dependency */
+		if (dp->name == wait_name) {
+			continue;
+		}
+		/*
+		 * For each pending target, look for a dependency which
+		 * is the same as a dependency of the subtree target.  Since
+		 * we can't build the subtree until all pending targets have
+		 * finished which depend on the same dependency, this is
+		 * a conflict.
+		 */
+		for (rp = running_list; rp != NULL; rp = rp->next) {
+			if (rp->state == build_pending) {
+				pending_line = get_prop(rp->target->prop,
+							line_prop);
+				if (pending_line == NULL) {
+					continue;
+				}
+				for(pending_dp = pending_line->
+				    			body.line.dependencies;
+				    pending_dp != NULL;
+				    pending_dp = pending_dp->next) {
+					if (dp->name == pending_dp->name) {
+						target->checking_subtree
+						  		= false;
+						subtree_conflict = rp->target;
+						subtree_conflict2 = dp->name;
+						return true;
+					}
+				}
+			}
+		}
+		if (dependency_conflict(dp->name)) {
+			target->checking_subtree = false;
+			return true;
+		}
+	}
+	target->checking_subtree = false;
+	return false;
+}
+
+/*
+ *	await_parallel(waitflg)
+ *
+ *	Waits for parallel children to exit and finishes their processing.
+ *	If waitflg is false, the function returns after update_delay.
+ *
+ *	Parameters:
+ *		waitflg		dwight
+ */
+void
+await_parallel(Boolean waitflg)
+{
+#ifdef _CHECK_UPDATE_H
+	static int number_of_unknown_children = 0;
+#endif /* _CHECK_UPDATE_H */
+	Boolean		nohang;
+	pid_t		pid;
+	int		status;
+	Running		rp;
+	int		waiterr;
+
+	nohang = false;
+	for ( ; ; ) {
+		if (!nohang) {
+			(void) alarm((int) update_delay);
+		}
+		pid = waitpid((pid_t)-1,
+			      &status,
+			      nohang ? WNOHANG : 0);
+		waiterr = errno;
+		if (!nohang) {
+			(void) alarm(0);
+		}
+		if (pid <= 0) {
+			if (waiterr == EINTR) {
+				if (waitflg) {
+					continue;
+				} else {
+					return;
+				}
+			} else {
+				return;
+			}
+		}
+		for (rp = running_list;
+		     (rp != NULL) && (rp->pid != pid);
+		     rp = rp->next) {
+			;
+		}
+		if (rp == NULL) {
+#ifdef _CHECK_UPDATE_H
+			/* Ignore first child - it is check_update */
+			if (number_of_unknown_children <= 0) {
+				number_of_unknown_children = 1;
+				return;
+			}
+#endif /* _CHECK_UPDATE_H */
+			if (send_mtool_msgs) {
+				continue;
+			} else {
+				fatal(catgets(catd, 1, 128, "Internal error: returned child pid not in running_list"));
+			}
+		} else {
+			rp->state = (WIFEXITED(status) && WEXITSTATUS(status) == 0) ? build_ok : build_failed;
+		}
+		nohang = true;
+		parallel_process_cnt--;
+
+#if defined (TEAMWARE_MAKE_CMN) && defined (MAXJOBS_ADJUST_RFE4694000)
+		if (job_adjust_mode == ADJUST_M2) {
+			if (m2_release_job()) {
+				job_adjust_error();
+			}
+		}
+#endif
+	}
+}
+
+/*
+ *	finish_children(docheck)
+ *
+ *	Finishes the processing for all targets which were running
+ *	and have now completed.
+ *
+ *	Parameters:
+ *		docheck		Completely check the finished target
+ *
+ *	Static variables used:
+ *		running_tail	The tail of the running list
+ *
+ *	Global variables used:
+ *		continue_after_error  -k flag
+ *		fatal_in_progress  True if we are finishing up after fatal err
+ *		running_list	List of running processes
+ */
+void
+finish_children(Boolean docheck)
+{
+	int		cmds_length;
+	Property	line;
+	Property	line2;
+	struct stat	out_buf;
+	Running		rp;
+	Running		*rp_prev;
+	Cmd_line	rule;
+	Boolean		silent_flag;
+
+	for (rp_prev = &running_list, rp = running_list;
+	     rp != NULL;
+	     rp = rp->next) {
+bypass_for_loop_inc_4:
+		/*
+		 * If the state is ok or failed, then this target has
+		 * finished building.
+		 * In parallel_mode, output the accumulated stdout/stderr.
+		 * Read the auto dependency stuff, handle a failed build,
+		 * update the target, then finish the doname process for
+		 * that target.
+		 */
+		if (rp->state == build_ok || rp->state == build_failed) {
+			*rp_prev = rp->next;
+			if (rp->next == NULL) {
+				running_tail = rp_prev;
+			}
+			if ((line2 = rp->command) == NULL) {
+				line2 = get_prop(rp->target->prop, line_prop);
+			}
+			if (dmake_mode_type == distributed_mode) {
+				if (rp->make_refd) {
+					maybe_reread_make_state();
+				}
+			} else {
+				/*
+				 * Send an Avo_MToolJobResultMsg to maketool.
+				 */
+#ifdef DISTRIBUTED
+				if (send_mtool_msgs) {
+					send_job_result_msg(rp);
+				}
+#endif
+				/*
+				 * Check if there were any job output
+				 * from the parallel build.
+				 */
+				if (rp->stdout_file != NULL) {
+					if (stat(rp->stdout_file, &out_buf) < 0) {
+						fatal(catgets(catd, 1, 130, "stat of %s failed: %s"),
+						      rp->stdout_file,
+						      errmsg(errno));
+					}
+					if ((line2 != NULL) &&
+					    (out_buf.st_size > 0)) {
+						cmds_length = 0;
+						for (rule = line2->body.line.command_used,
+						     silent_flag = silent;
+						     rule != NULL;
+						     rule = rule->next) {
+							cmds_length += rule->command_line->hash.length + 1;
+							silent_flag = BOOLEAN(silent_flag || rule->silent);
+						}
+						if (out_buf.st_size != cmds_length || silent_flag ||
+						    output_mode == txt2_mode) {
+							dump_out_file(rp->stdout_file, false);
+						}
+					}
+					(void) unlink(rp->stdout_file);
+					retmem_mb(rp->stdout_file);
+					rp->stdout_file = NULL;
+				}
+#if defined(REDIRECT_ERR)
+				if (!out_err_same && (rp->stderr_file != NULL)) {
+					if (stat(rp->stderr_file, &out_buf) < 0) {
+						fatal(catgets(catd, 1, 130, "stat of %s failed: %s"),
+						      rp->stderr_file,
+						      errmsg(errno));
+					}
+					if ((line2 != NULL) &&
+					    (out_buf.st_size > 0)) {
+						dump_out_file(rp->stderr_file, true);
+					}
+					(void) unlink(rp->stderr_file);
+					retmem_mb(rp->stderr_file);
+					rp->stderr_file = NULL;
+				}
+#endif
+			}
+			check_state(rp->temp_file);
+			if (rp->temp_file != NULL) {
+				free_name(rp->temp_file);
+			}
+			rp->temp_file = NULL;
+			if (rp->state == build_failed) {
+				line = get_prop(rp->target->prop, line_prop);
+				if (line != NULL) {
+					line->body.line.command_used = NULL;
+				}
+				if (continue_after_error ||
+				    fatal_in_progress ||
+				    !docheck) {
+					warning(catgets(catd, 1, 256, "Command failed for target `%s'"),
+						rp->command ? line2->body.line.target->string_mb : rp->target->string_mb);
+					build_failed_seen = true;
+				} else {
+					/*
+					 * XXX??? - DMake needs to exit(),
+					 * but shouldn't call fatal().
+					 */
+#ifdef PRINT_EXIT_STATUS
+					warning(NOCATGETS("I'm in finish_children. rp->state == build_failed."));
+#endif
+
+					fatal(catgets(catd, 1, 258, "Command failed for target `%s'"),
+						rp->command ? line2->body.line.target->string_mb : rp->target->string_mb);
+				}
+			}
+			if (!docheck) {
+				delete_running_struct(rp);
+				rp = *rp_prev;
+				if (rp == NULL) {
+					break;
+				} else {
+					goto bypass_for_loop_inc_4;
+				}
+			}
+			update_target(get_prop(rp->target->prop, line_prop),
+				      rp->state);
+			finish_doname(rp);
+			delete_running_struct(rp);
+			rp = *rp_prev;
+			if (rp == NULL) {
+				break;
+			} else {
+				goto bypass_for_loop_inc_4;
+			}
+		} else {
+			rp_prev = &rp->next;
+		}
+	}
+}
+
+/*
+ *	dump_out_file(filename, err)
+ *
+ *	Write the contents of the file to stdout, then unlink the file.
+ *
+ *	Parameters:
+ *		filename	Name of temp file containing output
+ *
+ *	Global variables used:
+ */
+static void
+dump_out_file(char *filename, Boolean err)
+{
+	int		chars_read;
+	char		copybuf[BUFSIZ];
+	int		fd;
+	int		out_fd = (err ? 2 : 1);
+
+	if ((fd = open(filename, O_RDONLY)) < 0) {
+		fatal(catgets(catd, 1, 141, "open failed for output file %s: %s"),
+		      filename,
+		      errmsg(errno));
+	}
+	if (!silent && output_mode != txt2_mode) {
+		(void) fprintf(err ? stderr : stdout,
+		               err ?
+				catgets(catd, 1, 338, "%s --> Job errors\n") :
+				catgets(catd, 1, 259, "%s --> Job output\n"),
+		               local_host);
+		(void) fflush(err ? stderr : stdout);
+	}
+	for (chars_read = read(fd, copybuf, BUFSIZ);
+	     chars_read > 0;
+	     chars_read = read(fd, copybuf, BUFSIZ)) {
+		/*
+		 * Read buffers from the source file until end or error.
+		 */
+		if (write(out_fd, copybuf, chars_read) < 0) {
+			fatal(catgets(catd, 1, 260, "write failed for output file %s: %s"),
+			      filename,
+			      errmsg(errno));
+		}
+	}
+	(void) close(fd);
+	(void) unlink(filename);
+}
+
+/*
+ *	finish_doname(rp)
+ *
+ *	Completes the processing for a target which was left running.
+ *
+ *	Parameters:
+ *		rp		Running list entry for target
+ *
+ *	Global variables used:
+ *		debug_level	Debug flag
+ *		recursion_level	Indentation for debug output
+ */
+static void
+finish_doname(Running rp)
+{
+	int		auto_count = rp->auto_count;
+	Name		*automatics = rp->automatics;
+	Doname		result = rp->state;
+	Name		target = rp->target;
+	Name		true_target = rp->true_target;
+	Property	*conditionals;
+
+	recursion_level = rp->recursion_level;
+	if (result == build_ok) {
+		if (true_target == NULL) {
+			(void) printf(NOCATGETS("Target = %s\n"), target->string_mb);
+			(void) printf(NOCATGETS(" State = %d\n"), result);
+			fatal(NOCATGETS("Internal error: NULL true_target in finish_doname"));
+		}
+		/* If all went OK, set a nice timestamp */
+		if (true_target->stat.time == file_doesnt_exist) {
+			true_target->stat.time = file_max_time;
+		}
+	}
+	target->state = result;
+	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 =
+/*
+			  exists(member->body.member.member);
+ */
+			  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, 261, "%*sTarget `%s' acquired new dependencies from build, checking all dependencies\n"),
+				      recursion_level,
+				      "",
+				      true_target->string_mb);
+		}
+		target->rechecking_target = true;
+		target->state = build_running;
+
+		/* [tolik, Tue Mar 25 1997]
+		 * Fix for bug 4038824:
+		 *       command line options set by conditional macros get dropped
+		 * rp->conditional_cnt and rp->conditional_targets must be copied
+		 * to new 'rp' during add_pending(). Set_conditionals() stores
+		 * rp->conditional_targets to the global variable 'conditional_targets'
+		 * Add_pending() will use this variable to set up 'rp'.
+		 */
+		conditionals = set_conditionals(rp->conditional_cnt, rp->conditional_targets);
+		add_pending(target,
+			    recursion_level,
+			    rp->do_get,
+			    rp->implicit,
+			    true);
+		reset_conditionals(rp->conditional_cnt, rp->conditional_targets, conditionals);
+	}
+}
+
+/*
+ *	new_running_struct()
+ *
+ *	Constructor for Running struct. Creates a structure and initializes
+ *      its fields.
+ *
+ */
+static Running new_running_struct()
+{
+	Running		rp;
+
+	rp = ALLOC(Running);
+	rp->target = NULL;
+	rp->true_target = NULL;
+	rp->command = NULL;
+	rp->sprodep_value = NULL;
+	rp->sprodep_env = NULL;
+	rp->auto_count = 0;
+	rp->automatics = NULL;
+	rp->pid = -1;
+	rp->job_msg_id = -1;
+	rp->stdout_file = NULL;
+	rp->stderr_file = NULL;
+	rp->temp_file = NULL;
+	rp->next = NULL;
+	return rp;
+}
+
+/*
+ *	add_running(target, true_target, command, recursion_level, auto_count,
+ *					automatics, do_get, implicit)
+ *
+ *	Adds a record on the running list for this target, which
+ *	was just spawned and is running.
+ *
+ *	Parameters:
+ *		target		Target being built
+ *		true_target	True target for target
+ *		command		Running command.
+ *		recursion_level	Debug indentation level
+ *		auto_count	Count of automatic dependencies
+ *		automatics	List of automatic dependencies
+ *		do_get		Sccs get flag
+ *		implicit	Implicit flag
+ *
+ *	Static variables used:
+ *		running_tail	Tail of running list
+ *		process_running	PID of process
+ *
+ *	Global variables used:
+ *		current_line	Current line for target
+ *		current_target	Current target being built
+ *		stderr_file	Temporary file for stdout
+ *		stdout_file	Temporary file for stdout
+ *		temp_file_name	Temporary file for auto dependencies
+ */
+void
+add_running(Name target, Name true_target, Property command, int recursion_level, int auto_count, Name *automatics, Boolean do_get, Boolean implicit)
+{
+	Running		rp;
+	Name		*p;
+
+	rp = new_running_struct();
+	rp->state = build_running;
+	rp->target = target;
+	rp->true_target = true_target;
+	rp->command = command;
+	Property spro_val = get_prop(sunpro_dependencies->prop, macro_prop);
+	if(spro_val) {
+		rp->sprodep_value = spro_val->body.macro.value;
+		spro_val->body.macro.value = NULL;
+		spro_val = get_prop(sunpro_dependencies->prop, env_mem_prop);
+		if(spro_val) {
+			rp->sprodep_env = spro_val->body.env_mem.value;
+			spro_val->body.env_mem.value = NULL;
+		}
+	}
+	rp->recursion_level = recursion_level;
+	rp->do_get = do_get;
+	rp->implicit = implicit;
+	rp->auto_count = auto_count;
+	if (auto_count > 0) {
+		rp->automatics = (Name *) getmem(auto_count * sizeof (Name));
+		for (p = rp->automatics; auto_count > 0; auto_count--) {
+			*p++ = *automatics++;
+		}
+	} else {
+		rp->automatics = NULL;
+	}
+#ifdef DISTRIBUTED
+	if (dmake_mode_type == distributed_mode) {
+		rp->make_refd = called_make;
+		called_make = false;
+	} else
+#endif
+	{
+		rp->pid = process_running;
+		process_running = -1;
+		childPid = -1;
+	}
+	rp->job_msg_id = job_msg_id;
+	rp->stdout_file = stdout_file;
+	rp->stderr_file = stderr_file;
+	rp->temp_file = temp_file_name;
+	rp->redo = false;
+	rp->next = NULL;
+	store_conditionals(rp);
+	stdout_file = NULL;
+	stderr_file = NULL;
+	temp_file_name = NULL;
+	current_target = NULL;
+	current_line = NULL;
+	*running_tail = rp;
+	running_tail = &rp->next;
+}
+
+/*
+ *	add_pending(target, recursion_level, do_get, implicit, redo)
+ *
+ *	Adds a record on the running list for a pending target
+ *	(waiting for its dependents to finish running).
+ *
+ *	Parameters:
+ *		target		Target being built
+ *		recursion_level	Debug indentation level
+ *		do_get		Sccs get flag
+ *		implicit	Implicit flag
+ *		redo		True if this target is being redone
+ *
+ *	Static variables used:
+ *		running_tail	Tail of running list
+ */
+void
+add_pending(Name target, int recursion_level, Boolean do_get, Boolean implicit, Boolean redo)
+{
+	Running		rp;
+	rp = new_running_struct();
+	rp->state = build_pending;
+	rp->target = target;
+	rp->recursion_level = recursion_level;
+	rp->do_get = do_get;
+	rp->implicit = implicit;
+	rp->redo = redo;
+	store_conditionals(rp);
+	*running_tail = rp;
+	running_tail = &rp->next;
+}
+
+/*
+ *	add_serial(target, recursion_level, do_get, implicit)
+ *
+ *	Adds a record on the running list for a target which must be
+ *	executed in serial after others have finished.
+ *
+ *	Parameters:
+ *		target		Target being built
+ *		recursion_level	Debug indentation level
+ *		do_get		Sccs get flag
+ *		implicit	Implicit flag
+ *
+ *	Static variables used:
+ *		running_tail	Tail of running list
+ */
+void
+add_serial(Name target, int recursion_level, Boolean do_get, Boolean implicit)
+{
+	Running		rp;
+
+	rp = new_running_struct();
+	rp->target = target;
+	rp->recursion_level = recursion_level;
+	rp->do_get = do_get;
+	rp->implicit = implicit;
+	rp->state = build_serial;
+	rp->redo = false;
+	store_conditionals(rp);
+	*running_tail = rp;
+	running_tail = &rp->next;
+}
+
+/*
+ *	add_subtree(target, recursion_level, do_get, implicit)
+ *
+ *	Adds a record on the running list for a target which must be
+ *	executed in isolation after others have finished.
+ *
+ *	Parameters:
+ *		target		Target being built
+ *		recursion_level	Debug indentation level
+ *		do_get		Sccs get flag
+ *		implicit	Implicit flag
+ *
+ *	Static variables used:
+ *		running_tail	Tail of running list
+ */
+void
+add_subtree(Name target, int recursion_level, Boolean do_get, Boolean implicit)
+{
+	Running		rp;
+
+	rp = new_running_struct();
+	rp->target = target;
+	rp->recursion_level = recursion_level;
+	rp->do_get = do_get;
+	rp->implicit = implicit;
+	rp->state = build_subtree;
+	rp->redo = false;
+	store_conditionals(rp);
+	*running_tail = rp;
+	running_tail = &rp->next;
+}
+
+/*
+ *	store_conditionals(rp)
+ *
+ *	Creates an array of the currently active targets with conditional
+ *	macros (found in the chain conditional_targets) and puts that
+ *	array in the Running struct.
+ *
+ *	Parameters:
+ *		rp		Running struct for storing chain
+ *
+ *	Global variables used:
+ *		conditional_targets  Chain of current dynamic conditionals
+ */
+static void
+store_conditionals(Running rp)
+{
+	int		cnt;
+	Chain		cond_name;
+
+	if (conditional_targets == NULL) {
+		rp->conditional_cnt = 0;
+		rp->conditional_targets = NULL;
+		return;
+	}
+	cnt = 0;
+	for (cond_name = conditional_targets;
+	     cond_name != NULL;
+	     cond_name = cond_name->next) {
+		cnt++;
+	}
+	rp->conditional_cnt = cnt;
+	rp->conditional_targets = (Name *) getmem(cnt * sizeof(Name));
+	for (cond_name = conditional_targets;
+	     cond_name != NULL;
+	     cond_name = cond_name->next) {
+		rp->conditional_targets[--cnt] = cond_name->name;
+	}
+}
+
+/*
+ *	parallel_ok(target, line_prop_must_exists)
+ *
+ *	Returns true if the target can be run in parallel
+ *
+ *	Return value:
+ *				True if can run in parallel
+ *
+ *	Parameters:
+ *		target		Target being tested
+ *
+ *	Global variables used:
+ *		all_parallel	True if all targets default to parallel
+ *		only_parallel	True if no targets default to parallel
+ */
+Boolean
+parallel_ok(Name target, Boolean line_prop_must_exists)
+{
+	Boolean		assign;
+	Boolean		make_refd;
+	Property	line;
+	Cmd_line	rule;
+
+	assign = make_refd = false;
+	if (((line = get_prop(target->prop, line_prop)) == NULL) &&
+	    line_prop_must_exists) {
+		return false;
+	}
+	if (line != NULL) {
+		for (rule = line->body.line.command_used;
+		     rule != NULL;
+		     rule = rule->next) {
+			if (rule->assign) {
+				assign = true;
+			} else if (rule->make_refd) {
+				make_refd = true;
+			}
+		}
+	}
+	if (assign) {
+		return false;
+	} else if (target->parallel) {
+		return true;
+	} else if (target->no_parallel) {
+		return false;
+	} else if (all_parallel) {
+		return true;
+	} else if (only_parallel) {
+		return false;
+	} else if (make_refd) {
+		return false;
+	} else {
+		return true;
+	}
+}
+
+/*
+ *	is_running(target)
+ *
+ *	Returns true if the target is running.
+ *
+ *	Return value:
+ *				True if target is running
+ *
+ *	Parameters:
+ *		target		Target to check
+ *
+ *	Global variables used:
+ *		running_list	List of running processes
+ */
+Boolean
+is_running(Name target)
+{
+	Running		rp;
+
+	if (target->state != build_running) {
+		return false;
+	}
+	for (rp = running_list;
+	     rp != NULL && target != rp->target;
+	     rp = rp->next);
+	if (rp == NULL) {
+		return false;
+	} else {
+		return (rp->state == build_running) ? true : false;
+	}
+}
+
+/*
+ * This function replaces the makesh binary.
+ */
+ 
+#ifdef SGE_SUPPORT
+#define DO_CHECK(f)	if (f <= 0) { \
+				fprintf(stderr, \
+					catgets(catd, 1, 347, "Could not write to file: %s: %s\n"), \
+						script_file, errmsg(errno)); \
+				_exit(1); \
+			}
+#endif /* SGE_SUPPORT */
+
+static pid_t
+run_rule_commands(char *host, char **commands)
+{
+	Boolean		always_exec;
+	Name		command;
+	Boolean		ignore;
+	int		length;
+	Doname		result;
+	Boolean		silent_flag;
+#ifdef SGE_SUPPORT
+	wchar_t		*wcmd, *tmp_wcs_buffer = NULL;
+	char		*cmd, *tmp_mbs_buffer = NULL;
+	FILE		*scrfp;
+	Name		shell = getvar(shell_name);
+#else
+	wchar_t		*tmp_wcs_buffer;
+#endif /* SGE_SUPPORT */
+
+	childPid = fork();
+	switch (childPid) {
+	case -1:	/* Error */
+		fatal(catgets(catd, 1, 337, "Could not fork child process for dmake job: %s"),
+		      errmsg(errno));
+		break;
+	case 0:		/* Child */
+		/* To control the processed targets list is not the child's business */
+		running_list = NULL;
+#if defined(REDIRECT_ERR)
+		if(out_err_same) {
+			redirect_io(stdout_file, (char*)NULL);
+		} else {
+			redirect_io(stdout_file, stderr_file);
+		}
+#else
+		redirect_io(stdout_file, (char*)NULL);
+#endif
+#ifdef SGE_SUPPORT
+		if (grid) {
+			int fdes = mkstemp(script_file);
+			if ((fdes < 0) || (scrfp = fdopen(fdes, "w")) == NULL) {
+				fprintf(stderr,
+					catgets(catd, 1, 341, "Could not create file: %s: %s\n"),
+					script_file, errmsg(errno));
+				_exit(1);
+			}
+			if (IS_EQUAL(shell->string_mb, "")) {
+				shell = shell_name;
+			}
+		}
+#endif /* SGE_SUPPORT */
+		for (commands = commands;
+		     (*commands != (char *)NULL);
+		     commands++) {
+			silent_flag = silent;
+			ignore = false;
+			always_exec = false;
+			while ((**commands == (int) at_char) ||
+			       (**commands == (int) hyphen_char) ||
+			       (**commands == (int) plus_char)) {
+				if (**commands == (int) at_char) {
+					silent_flag = true;
+				}
+				if (**commands == (int) hyphen_char) {
+					ignore = true;
+				}
+				if (**commands == (int) plus_char) {
+					always_exec = true;
+				}
+				(*commands)++;
+			}
+#ifdef SGE_SUPPORT
+			if (grid) {
+				if ((length = strlen(*commands)) >= MAXPATHLEN / 2) {
+					wcmd = tmp_wcs_buffer = ALLOC_WC(length * 2 + 1);
+					(void) mbstowcs(tmp_wcs_buffer, *commands, length * 2 + 1);
+				} else {
+					MBSTOWCS(wcs_buffer, *commands);
+					wcmd = wcs_buffer;
+					cmd = mbs_buffer;
+				}
+				wchar_t	*from = wcmd + wslen(wcmd);
+				wchar_t	*to = from + (from - wcmd);
+				*to = (int) nul_char;
+				while (from > wcmd) {
+					*--to = *--from;
+					if (*from == (int) newline_char) { // newline symbols are already quoted
+						*--to = *--from;
+					} else if (wschr(char_semantics_char, *from)) {
+						*--to = (int) backslash_char;
+					}
+				}
+				if (length >= MAXPATHLEN*MB_LEN_MAX/2) { // sizeof(mbs_buffer) / 2
+					cmd = tmp_mbs_buffer = getmem((length * MB_LEN_MAX * 2) + 1);
+					(void) wcstombs(tmp_mbs_buffer, to, (length * MB_LEN_MAX * 2) + 1);
+				} else {
+					WCSTOMBS(mbs_buffer, to);
+					cmd = mbs_buffer;
+				}
+				char *mbst, *mbend;
+				if ((length > 0) &&
+				    !silent_flag) {
+				    	for (mbst = cmd; (mbend = strstr(mbst, "\\\n")) != NULL; mbst = mbend + 2) {
+						*mbend = '\0';
+						DO_CHECK(fprintf(scrfp, NOCATGETS("/usr/bin/printf '%%s\\n' %s\\\\\n"), mbst));
+						*mbend = '\\';
+					}
+					DO_CHECK(fprintf(scrfp, NOCATGETS("/usr/bin/printf '%%s\\n' %s\n"), mbst));
+				}
+				if (!do_not_exec_rule ||
+				    !working_on_targets ||
+				    always_exec) {
+#if defined(linux)
+					if (0 != strcmp(shell->string_mb, (char*)NOCATGETS("/bin/sh"))) {
+						DO_CHECK(fprintf(scrfp, NOCATGETS("%s -c %s\n"), shell->string_mb, cmd));
+					} else
+#endif
+					DO_CHECK(fprintf(scrfp, NOCATGETS("%s -ce %s\n"), shell->string_mb, cmd));
+					DO_CHECK(fputs(NOCATGETS("__DMAKECMDEXITSTAT=$?\nif [ ${__DMAKECMDEXITSTAT} -ne 0 ]; then\n"), scrfp));
+					if (ignore) {
+						DO_CHECK(fprintf(scrfp, NOCATGETS("\techo %s ${__DMAKECMDEXITSTAT} %s\n"),
+							catgets(catd, 1, 343, "\"*** Error code"),
+							catgets(catd, 1, 344, "(ignored)\"")));
+					} else {
+						DO_CHECK(fprintf(scrfp, NOCATGETS("\techo %s ${__DMAKECMDEXITSTAT}\n"),
+							catgets(catd, 1, 342, "\"*** Error code\"")));
+					}
+					if (silent_flag) {
+						DO_CHECK(fprintf(scrfp, NOCATGETS("\techo %s\n"),
+							catgets(catd, 1, 345, "The following command caused the error:")));
+				 	   	for (mbst = cmd; (mbend = strstr(mbst, "\\\n")) != NULL; mbst = mbend + 2) {
+							*mbend = '\0';
+							DO_CHECK(fprintf(scrfp, NOCATGETS("\t/usr/bin/printf '%%s\\n' %s\\\\\n"), mbst));
+							*mbend = '\\';
+						}
+						DO_CHECK(fprintf(scrfp, NOCATGETS("\t/usr/bin/printf '%%s\\n' %s\n"), mbst));
+					}
+					if (!ignore) {
+						DO_CHECK(fputs(NOCATGETS("\texit ${__DMAKECMDEXITSTAT}\n"), scrfp));
+					}
+					DO_CHECK(fputs(NOCATGETS("fi\n"), scrfp));
+				}
+				if (tmp_wcs_buffer) {
+					retmem_mb(tmp_mbs_buffer);
+					tmp_mbs_buffer = NULL;
+				}
+				if (tmp_wcs_buffer) {
+					retmem(tmp_wcs_buffer);
+					tmp_wcs_buffer = NULL;
+				}
+				continue;
+			}
+#endif /* SGE_SUPPORT */
+			if ((length = strlen(*commands)) >= MAXPATHLEN) {
+				tmp_wcs_buffer = ALLOC_WC(length + 1);
+				(void) mbstowcs(tmp_wcs_buffer, *commands, length + 1);
+				command = GETNAME(tmp_wcs_buffer, FIND_LENGTH);
+				retmem(tmp_wcs_buffer);
+			} else {
+				MBSTOWCS(wcs_buffer, *commands);
+				command = GETNAME(wcs_buffer, FIND_LENGTH);
+			}
+			if ((command->hash.length > 0) &&
+			    !silent_flag) {
+				(void) printf("%s\n", command->string_mb);
+			}
+			result = dosys(command,
+			               ignore,
+			               false,
+			               false, /* bugs #4085164 & #4990057 */
+			               /* BOOLEAN(silent_flag && ignore), */
+			               always_exec, 
+			               (Name) NULL,
+			               false);
+			if (result == build_failed) {
+				if (silent_flag) {
+					(void) printf(catgets(catd, 1, 152, "The following command caused the error:\n%s\n"), command->string_mb);
+				}
+				if (!ignore) {
+					_exit(1);
+				}
+			}
+		}
+#ifndef SGE_SUPPORT
+		_exit(0);
+#else
+		if (!grid) {
+			_exit(0);
+		}
+		DO_CHECK(fputs(NOCATGETS("exit 0\n"), scrfp));
+		if (fclose(scrfp) != 0) {
+			fprintf(stderr,
+				catgets(catd, 1, 346, "Could not close file: %s: %s\n"),
+				script_file, errmsg(errno));
+			_exit(1);
+		}
+		{
+
+#define DEFAULT_QRSH_TRIES_NUMBER	1
+#define DEFAULT_QRSH_TIMEOUT		0
+
+		static char	*sge_env_var = NULL;
+		static int	qrsh_tries_number = DEFAULT_QRSH_TRIES_NUMBER;
+		static int	qrsh_timeout = DEFAULT_QRSH_TIMEOUT;
+#define SGE_DEBUG
+#ifdef SGE_DEBUG
+		static	Boolean do_not_remove = false;
+#endif /* SGE_DEBUG */
+		if (sge_env_var == NULL) {
+			sge_env_var = getenv(NOCATGETS("__SPRO_DMAKE_SGE_TRIES"));
+			if (sge_env_var != NULL) {
+				qrsh_tries_number = atoi(sge_env_var);
+				if (qrsh_tries_number < 1 || qrsh_tries_number > 9) {
+					qrsh_tries_number = DEFAULT_QRSH_TRIES_NUMBER;
+				}
+			}
+			sge_env_var = getenv(NOCATGETS("__SPRO_DMAKE_SGE_TIMEOUT"));
+			if (sge_env_var != NULL) {
+				qrsh_timeout = atoi(sge_env_var);
+				if (qrsh_timeout <= 0) {
+					qrsh_timeout = DEFAULT_QRSH_TIMEOUT;
+				}
+			} else {
+				sge_env_var = "";
+			}
+#ifdef SGE_DEBUG
+			sge_env_var = getenv(NOCATGETS("__SPRO_DMAKE_SGE_DEBUG"));
+			if (sge_env_var == NULL) {
+				sge_env_var = "";
+			}
+			if (strstr(sge_env_var, NOCATGETS("noqrsh")) != NULL)
+				qrsh_tries_number = 0;
+			if (strstr(sge_env_var, NOCATGETS("donotremove")) != NULL)
+				do_not_remove = true;
+#endif /* SGE_DEBUG */
+		}
+		for (int i = qrsh_tries_number; ; i--)
+		if ((childPid = fork()) < 0) {
+			fatal(catgets(catd, 1, 348, "Could not fork child process for qrsh job: %s"),
+		      		errmsg(errno));
+			_exit(1);
+		} else if (childPid == 0) {
+			enable_interrupt((void (*) (int))SIG_DFL);
+			if (i > 0) {
+				static char qrsh_cmd[50+MAXPATHLEN] = NOCATGETS("qrsh -cwd -V -noshell -nostdin /bin/sh ");
+				static char *fname_ptr = NULL;
+				static char *argv[] = { NOCATGETS("sh"),
+							NOCATGETS("-fce"),
+							qrsh_cmd,
+							NULL};
+				if (fname_ptr == NULL) {
+					fname_ptr = qrsh_cmd + strlen(qrsh_cmd);
+				}
+				strcpy(fname_ptr, script_file);
+				(void) execve(NOCATGETS("/bin/sh"), argv, environ);
+			} else {
+				static char *argv[] = { NOCATGETS("sh"),
+							script_file,
+							NULL};
+				(void) execve(NOCATGETS("/bin/sh"), argv, environ);
+			}
+			fprintf(stderr,
+				catgets(catd, 1, 349, "Could not load `qrsh': %s\n"),
+				errmsg(errno));
+			_exit(1);
+		} else {
+#if defined (HP_UX) || defined (linux) || defined (SUN5_0)
+			int		status;
+#else
+			union wait	status;
+#endif
+			pid_t pid;
+			while ((pid = wait(&status)) != childPid) {
+				if (pid == -1) {
+					fprintf(stderr,
+						catgets(catd, 1, 350, "wait() failed: %s\n"),
+						errmsg(errno));
+					_exit(1);
+				}
+			}
+			if (status != 0 && i > 0) {
+				if (i > 1) {
+					sleep(qrsh_timeout);
+				}
+				continue;
+			}
+#ifdef SGE_DEBUG
+			if (do_not_remove) {
+				if (status) {
+					fprintf(stderr,
+						NOCATGETS("SGE script failed: %s\n"),
+						script_file);
+				}
+				_exit(status ? 1 : 0);
+			}
+#endif /* SGE_DEBUG */
+			(void) unlink(script_file);
+			_exit(status ? 1 : 0);
+		}
+		}
+#endif /* SGE_SUPPORT */
+		break;
+	default:
+		break;
+	}
+	return childPid;
+}
+
+static void
+maybe_reread_make_state(void)
+{
+	/* Copying dosys()... */
+	if (report_dependencies_level == 0) {
+		make_state->stat.time = file_no_time;
+		(void) exists(make_state);
+		if (make_state_before == make_state->stat.time) {
+			return;
+		}
+		makefile_type = reading_statefile;
+		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;
+	}
+}
+
+#ifdef DISTRIBUTED
+/*
+ * Create and send an Avo_MToolJobResultMsg.
+ */
+static void
+send_job_result_msg(Running rp)
+{
+	Avo_MToolJobResultMsg	*msg;
+	RWCollectable		*xdr_msg;
+
+	msg = new Avo_MToolJobResultMsg();
+	msg->setResult(rp->job_msg_id,
+	               (rp->state == build_ok) ? 0 : 1,
+	               DONE);
+	append_job_result_msg(msg,
+				rp->stdout_file,
+				rp->stderr_file);
+
+	xdr_msg = (RWCollectable *)msg;
+	xdr(get_xdrs_ptr(), xdr_msg);
+	(void) fflush(get_mtool_msgs_fp());
+
+	delete msg;
+}
+
+/*
+ * Append the stdout/err to Avo_MToolJobResultMsg.
+ */
+static void
+append_job_result_msg(Avo_MToolJobResultMsg *msg, char *outFn, char *errFn)
+{
+	FILE		*fp;
+	char		line[MAXPATHLEN];
+
+	fp = fopen(outFn, "r");
+	if (fp == NULL) {
+		/* Hmmm... what should we do here? */
+		return;
+	}
+	while (fgets(line, MAXPATHLEN, fp) != NULL) {
+		if (line[strlen(line) - 1] == '\n') {
+			line[strlen(line) - 1] = '\0';
+		}
+		msg->appendOutput(AVO_STRDUP(line));
+	}
+	(void) fclose(fp);
+}
+#endif
+
+static void
+delete_running_struct(Running rp)
+{
+	if ((rp->conditional_cnt > 0) &&
+	    (rp->conditional_targets != NULL)) {
+		retmem_mb((char *) rp->conditional_targets);
+	}
+/**/
+	if ((rp->auto_count > 0) &&
+	    (rp->automatics != NULL)) {
+		retmem_mb((char *) rp->automatics);
+	}
+/**/
+	if(rp->sprodep_value) {
+		free_name(rp->sprodep_value);
+	}
+	if(rp->sprodep_env) {
+		retmem_mb(rp->sprodep_env);
+	}
+	retmem_mb((char *) rp);
+
+}
+
+#endif
+
--- /dev/null	2015-05-20 11:04:10.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/common/pmake.cc	2015-05-20 11:04:10.639612481 -0400
@@ -0,0 +1,434 @@
+/*
+ * 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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)pmake.cc 1.9 06/12/12
+ */
+
+#pragma	ident	"@(#)pmake.cc	1.9	06/12/12"
+
+#ifdef TEAMWARE_MAKE_CMN
+
+/*
+ * Included files
+ */
+#include <arpa/inet.h>
+#include <mk/defs.h>
+#include <mksh/misc.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include <rpc/rpc.h>		/* host2netname(), netname2host() */
+#ifdef linux
+#	include <unistd.h>	/* getdomainname() */
+#endif
+
+/*
+ * Defined macros
+ */
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+
+/*
+ * File table of contents
+ */
+static int		get_max(wchar_t **ms_address, wchar_t *hostname);
+static Boolean		pskip_comment(wchar_t **cp_address);
+static void		pskip_till_next_word(wchar_t **cp);
+static Boolean		pskip_white_space(wchar_t **cp_address);
+
+
+/*
+ *	read_make_machines(Name make_machines_name)
+ *
+ *	For backwards compatibility w/ PMake 1.x, when DMake 2.x is
+ *	being run in parallel mode, DMake should parse the PMake startup
+ *	file $(HOME)/.make.machines to get the PMake max jobs.
+ *
+ *	Return value:
+ *		int of PMake max jobs
+ *
+ *	Parameters:
+ *		make_machines_name	Name of .make.machines file
+ *
+ */
+int
+read_make_machines(Name make_machines_name)
+{
+	wchar_t 		c;
+	Boolean			default_make_machines;
+	struct hostent		*hp;
+	wchar_t			local_host[MAX_HOSTNAMELEN + 1];
+	char			local_host_mb[MAX_HOSTNAMELEN + 1] = "";
+	int			local_host_wslen;
+	wchar_t			full_host[MAXNETNAMELEN + 1];
+	int			full_host_wslen = 0;
+	char			*homedir;
+	Name			MAKE_MACHINES;
+	struct stat		make_machines_buf;
+	FILE			*make_machines_file;
+	wchar_t			*make_machines_list = NULL;
+	char			*make_machines_list_mb = NULL;
+	wchar_t			make_machines_path[MAXPATHLEN];
+	char			mb_make_machines_path[MAXPATHLEN];
+	wchar_t			*mp;
+	wchar_t			*ms;
+	int			pmake_max_jobs = 0;
+	struct utsname		uts_info;
+
+
+	MBSTOWCS(wcs_buffer, NOCATGETS("MAKE_MACHINES"));
+	MAKE_MACHINES = GETNAME(wcs_buffer, FIND_LENGTH);
+	/* Did the user specify a .make.machines file on the command line? */
+	default_make_machines = false;
+	if (make_machines_name == NULL) {
+		/* Try reading the default .make.machines file, in $(HOME). */
+		homedir = getenv(NOCATGETS("HOME"));
+		if ((homedir != NULL) && (strlen(homedir) < (sizeof(mb_make_machines_path) - 16))) {
+			sprintf(mb_make_machines_path,
+			 NOCATGETS("%s/.make.machines"), homedir);
+			MBSTOWCS(make_machines_path, mb_make_machines_path);
+			make_machines_name = GETNAME(make_machines_path, FIND_LENGTH);
+			default_make_machines = true;
+		}
+		if (make_machines_name == NULL) {
+			/*
+			 * No $(HOME)/.make.machines file.
+			 * Return 0 for PMake max jobs.
+			 */
+			return(0);
+		}
+	}
+/*
+	make_machines_list_mb = getenv(MAKE_MACHINES->string_mb);
+ */
+	/* Open the .make.machines file. */
+	if ((make_machines_file = fopen(make_machines_name->string_mb, "r")) == NULL) {
+		if (!default_make_machines) {
+			/* Error opening .make.machines file. */
+			fatal(catgets(catd, 1, 314, "Open of %s failed: %s"),
+			      make_machines_name->string_mb,
+			      errmsg(errno));
+		} else {
+			/*
+			 * No $(HOME)/.make.machines file.
+			 * Return 0 for PMake max jobs.
+			 */
+			return(0);
+		}
+	/* Stat the .make.machines file to get the size of the file.  */
+	} else if (fstat(fileno(make_machines_file), &make_machines_buf) < 0) {
+		/* Error stat'ing .make.machines file. */
+		fatal(catgets(catd, 1, 315, "Stat of %s failed: %s"),
+		      make_machines_name->string_mb,
+		      errmsg(errno));
+	} else {
+		/* Allocate memory for "MAKE_MACHINES=<contents of .m.m>" */
+		make_machines_list_mb =
+		  (char *) getmem((int) (strlen(MAKE_MACHINES->string_mb) +
+		                         2 +
+		                         make_machines_buf.st_size));
+		sprintf(make_machines_list_mb,
+			"%s=",
+			MAKE_MACHINES->string_mb);
+		/* Read in the .make.machines file. */
+		if (fread(make_machines_list_mb + strlen(MAKE_MACHINES->string_mb) + 1,
+			  sizeof(char),
+			  (int) make_machines_buf.st_size,
+			  make_machines_file) != make_machines_buf.st_size) {
+			/*
+			 * Error reading .make.machines file.
+			 * Return 0 for PMake max jobs.
+			 */
+			warning(catgets(catd, 1, 316, "Unable to read %s"),
+				make_machines_name->string_mb);
+			(void) fclose(make_machines_file);
+			retmem_mb((caddr_t) make_machines_list_mb);
+			return(0);
+		} else {
+			(void) fclose(make_machines_file);
+			/* putenv "MAKE_MACHINES=<contents of .m.m>" */
+			*(make_machines_list_mb +
+			  strlen(MAKE_MACHINES->string_mb) +
+			  1 +
+			  make_machines_buf.st_size) = (int) nul_char;
+			if (putenv(make_machines_list_mb) != 0) {
+				warning(catgets(catd, 1, 317, "Couldn't put contents of %s in environment"),
+					make_machines_name->string_mb);
+			} else {
+				make_machines_list_mb += strlen(MAKE_MACHINES->string_mb) + 1;
+				make_machines_list = ALLOC_WC(strlen(make_machines_list_mb) + 1);
+				(void) mbstowcs(make_machines_list,
+				                make_machines_list_mb,
+				                (strlen(make_machines_list_mb) + 1));
+			}
+		}
+	}
+
+	uname(&uts_info);
+	strcpy(local_host_mb, &uts_info.nodename[0]);
+	MBSTOWCS(local_host, local_host_mb);
+	local_host_wslen = wslen(local_host);
+
+	// There is no getdomainname() function on Solaris.
+	// And netname2host() function does not work on Linux.
+	// So we have to use different APIs.
+#ifdef linux
+	if (getdomainname(mbs_buffer, MAXNETNAMELEN+1) == 0) {
+		sprintf(mbs_buffer2, "%s.%s", local_host_mb, mbs_buffer);
+#else
+	if (host2netname(mbs_buffer, NULL, NULL) &&
+	    netname2host(mbs_buffer, mbs_buffer2, MAXNETNAMELEN+1)) {
+#endif
+		MBSTOWCS(full_host, mbs_buffer2);
+		full_host_wslen = wslen(full_host);
+	}
+
+	for (ms = make_machines_list;
+	     (ms) && (*ms );
+	     ) {
+		/*
+		 * Skip white space and comments till you reach
+		 * a machine name.
+		 */
+		pskip_till_next_word(&ms);
+
+		/*
+		 * If we haven't reached the end of file, process the
+		 * machine name.
+		 */
+		if (*ms) {
+			/* 
+			 * If invalid machine name decrement counter 
+			 * and skip line.
+			 */
+			mp = ms;
+			SKIPWORD(ms);
+			c = *ms;
+			*ms++ = '\0'; /* Append null to machine name. */
+			/*
+			 * If this was the beginning of a comment
+			 * (we overwrote a # sign) and it's not
+			 * end of line yet, shift the # sign.
+			 */
+			if ((c == '#') && (*ms != '\n') && (*ms)) {
+				*ms = '#';
+			}
+			WCSTOMBS(mbs_buffer, mp);
+			/*
+			 * Print "Ignoring unknown host" if:
+			 * 1) hostname is longer than MAX_HOSTNAMELEN, or
+			 * 2) hostname is unknown
+			 */
+			if ((wslen(mp) > MAX_HOSTNAMELEN) ||
+			    ((hp = gethostbyname(mbs_buffer)) == NULL)) {
+				warning(catgets(catd, 1, 318, "Ignoring unknown host %s"),
+					mbs_buffer);
+				SKIPTOEND(ms);
+				/* Increment ptr if not end of file. */
+				if (*ms) {
+					ms++;
+				}
+			} else {
+				/* Compare current hostname with local_host. */
+				if (wslen(mp) == local_host_wslen &&
+				    IS_WEQUALN(mp, local_host, local_host_wslen)) {
+					/*
+					 * Bingo, local_host is in .make.machines.
+					 * Continue reading.
+					 */
+					pmake_max_jobs = PMAKE_DEF_MAX_JOBS;
+				/* Compare current hostname with full_host. */
+				} else if (wslen(mp) == full_host_wslen &&
+					   IS_WEQUALN(mp, full_host, full_host_wslen)) {
+					/*
+					 * Bingo, full_host is in .make.machines.
+					 * Continue reading.
+					 */
+					pmake_max_jobs = PMAKE_DEF_MAX_JOBS;
+				} else {
+					if (c != '\n') {
+					    SKIPTOEND(ms);
+					    if (*ms) {
+						ms++;
+					    }
+					}
+					continue;
+				}
+				/* If we get here, local_host is in .make.machines. */
+				if (c != '\n')  {
+					/* Now look for keyword 'max'. */
+					MBSTOWCS(wcs_buffer, NOCATGETS("max"));
+					SKIPSPACE(ms);
+					while ((*ms != '\n') && (*ms)) {
+						if (*ms == '#') {
+							pskip_comment(&ms);
+						} else if (IS_WEQUALN(ms, wcs_buffer, 3)) {
+							/* Skip "max". */
+							ms += 3; 
+							pmake_max_jobs = get_max(&ms, mp); 
+							SKIPSPACE(ms);
+						} else {
+							warning(catgets(catd, 1, 322, "unknown option for host %s"), mbs_buffer);
+							SKIPTOEND(ms);
+							break;
+						}
+					}
+				}
+				break; /* out of outermost for() loop. */
+			}
+		}
+	}
+	retmem(make_machines_list);
+	return(pmake_max_jobs);
+}
+
+/*
+ *	pskip_till_next_word(cp)
+ *
+ *	Parameters:
+ *		cp		the address of the string pointer.
+ *
+ *	On return:
+ *		cp		points to beginning of machine name.
+ *
+ */
+static void
+pskip_till_next_word(wchar_t **cp)
+{
+	/*
+	 * Keep recursing until all combinations of white spaces
+	 * and comments have been skipped.
+	 */
+	if (pskip_white_space(cp) || pskip_comment(cp)) {
+		pskip_till_next_word(cp);
+	}
+}
+
+/*
+ *	pskip_white_space(cp_address)
+ *
+ *	Advances the string pointer so that it points to the first
+ *	non white character (space/tab/linefeed).
+ *
+ *	Parameters:
+ *		cp_address	the address of the string pointer.
+ *
+ *	Return Value:
+ *				True if the pointer was changed.
+ *
+ */
+static Boolean
+pskip_white_space(wchar_t **cp_address)
+{
+	wchar_t		*cp = *cp_address;
+
+	while (*cp && iswspace(*cp)) {
+		cp++;
+	}
+	/* Have we skipped any characters? */
+	if (cp != *cp_address) {
+		*cp_address = cp;
+		return(true);
+	} else {
+		return(false);
+	}
+}
+
+/*
+ *	pskip_comment(cp_address)
+ *
+ *	If cp_address is pointing to '#' (the beginning of a comment),
+ *	increment the pointer till you reach end of line.
+ *
+ *	Parameters:
+ *		cp_address	the address of the string pointer.
+ *
+ *	Return Value:
+ *				True if the pointer was changed.
+ *
+ */
+static Boolean
+pskip_comment(wchar_t **cp_address)
+{
+	wchar_t		*cp = *cp_address;
+
+	/* Is this the beginning of a comment? Skip till end of line. */
+	if (*cp == '#') {
+		SKIPTOEND(cp);
+	}
+	/* Have we skipped a comment line? */
+	if (cp != *cp_address)	{
+		*cp_address = cp;
+		return(true);
+	} else {
+		return(false);
+	}
+}
+
+static int
+get_max(wchar_t **ms_address, wchar_t *hostname)
+{
+	wchar_t 	*ms = *ms_address;
+	int		limit = PMAKE_DEF_MAX_JOBS; /* Default setting. */
+
+	WCSTOMBS(mbs_buffer, hostname);
+	/* Look for `='. */
+	SKIPSPACE(ms);
+	if ((!*ms) || (*ms == '\n') || (*ms != '=')) {
+		SKIPTOEND(ms);
+		warning(catgets(catd, 1, 319, "expected `=' after max, ignoring rest of line for host %s"),
+			mbs_buffer);
+		*ms_address = ms;
+		return((int) limit);
+	} else {
+		ms++;
+		SKIPSPACE(ms);
+		if ((*ms != '\n') && (*ms != '\0')) {
+			/* We've found, hopefully, a valid "max" value. */
+			limit = (int) wcstol(ms, &ms, 10);
+			if (limit < 1) {
+				limit = PMAKE_DEF_MAX_JOBS;
+				warning(catgets(catd, 1, 320, "max value cannot be less than or equal to zero for host %s"), mbs_buffer);
+			}
+		} else {
+			/* No "max" value after "max=". */
+			warning(catgets(catd, 1, 321, "no max value specified for host %s"), mbs_buffer);
+		}
+		*ms_address = ms;
+		return(limit);
+	}
+}
+
+#endif
+
--- /dev/null	2015-05-20 11:04:10.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/common/read.cc	2015-05-20 11:04:10.836058782 -0400
@@ -0,0 +1,2197 @@
+/*
+ * 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.
+ */
+/*
+ * @(#)read.cc 1.64 06/12/12
+ */
+
+#pragma	ident	"@(#)read.cc	1.64	06/12/12"
+
+/*
+ *	read.c
+ *
+ *	This file contains the makefile reader.
+ */
+
+/*
+ * Included files
+ */
+#include <avo/avo_alloca.h>		/* alloca() */
+#include <errno.h>		/* errno */
+#include <fcntl.h>		/* fcntl() */
+#include <mk/defs.h>
+#include <mksh/macro.h>		/* expand_value(), expand_macro() */
+#include <mksh/misc.h>		/* getmem() */
+#include <mksh/read.h>		/* get_next_block_fn() */
+#include <sys/uio.h>		/* read() */
+#include <unistd.h>		/* read(), unlink() */
+
+#if defined(HP_UX) || defined(linux)
+#include <avo/types.h>
+extern "C" Avo_err *avo_find_run_dir(char **dirp);
+#endif
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+
+static int line_started_with_space=0; // Used to diagnose spaces instead of tabs
+
+/*
+ * File table of contents
+ */
+static	void		parse_makefile(register Name true_makefile_name, register Source source);
+static	Source		push_macro_value(register Source bp, register wchar_t *buffer, int size, register Source source);
+extern  void 		enter_target_groups_and_dependencies(Name_vector target, Name_vector depes, Cmd_line command, Separator separator, Boolean target_group_seen);
+extern	Name		normalize_name(register wchar_t *name_string, register int length);
+
+/*
+ *	read_simple_file(makefile_name, chase_path, doname_it,
+ *		 complain, must_exist, report_file, lock_makefile)
+ *
+ *	Make the makefile and setup to read it. Actually read it if it is stdio
+ *
+ *	Return value:
+ *				false if the read failed
+ *
+ *	Parameters:
+ *		makefile_name	Name of the file to read
+ *		chase_path	Use the makefile path when opening file
+ *		doname_it	Call doname() to build the file first
+ *		complain	Print message if doname/open fails
+ *		must_exist	Generate fatal if file is missing
+ *		report_file	Report file when running -P
+ *		lock_makefile	Lock the makefile when reading
+ *
+ *	Static variables used:
+ *
+ *	Global variables used:
+ *		do_not_exec_rule Is -n on?
+ *		file_being_read	Set to the name of the new file
+ *		line_number	The number of the current makefile line
+ *		makefiles_used	A list of all makefiles used, appended to
+ */
+
+
+Boolean
+read_simple_file(register Name makefile_name, register Boolean chase_path, register Boolean doname_it, Boolean complain, Boolean must_exist, Boolean report_file, Boolean lock_makefile)
+{
+	static short		max_include_depth;
+	register Property	makefile = maybe_append_prop(makefile_name,
+							     makefile_prop);
+	Boolean			forget_after_parse = false;
+	static pathpt		makefile_path;
+	register int		n;
+	char			*path;
+	register Source		source = ALLOC(Source);
+	Property		orig_makefile = makefile;
+	Dependency		*dpp;
+	Dependency		dp;
+	register int		length;
+	wchar_t			*previous_file_being_read = file_being_read;
+	int			previous_line_number = line_number;
+	wchar_t			previous_current_makefile[MAXPATHLEN];
+	Makefile_type		save_makefile_type;
+	Name 			normalized_makefile_name;
+	register wchar_t        *string_start;
+	register wchar_t        *string_end;
+
+
+#if defined(HP_UX) || defined(linux)
+	Avo_err                 *findrundir_err;
+	char                    *run_dir, makerules_dir[BUFSIZ];
+#endif
+
+	wchar_t * wcb = get_wstring(makefile_name->string_mb);
+
+#ifdef NSE
+	if (report_file){
+		wscpy(previous_current_makefile, current_makefile);
+		wscpy(current_makefile, wcb);
+	}
+#endif 
+	if (max_include_depth++ >= 40) {
+		fatal(catgets(catd, 1, 66, "Too many nested include statements"));
+	}
+	if (makefile->body.makefile.contents != NULL) {
+		retmem(makefile->body.makefile.contents);
+	}
+	source->inp_buf =
+	  source->inp_buf_ptr =
+	    source->inp_buf_end = NULL;
+	source->error_converting = false;
+	makefile->body.makefile.contents = NULL;
+	makefile->body.makefile.size = 0;
+	if ((makefile_name->hash.length != 1) ||
+	    (wcb[0] != (int) hyphen_char)) {
+		if ((makefile->body.makefile.contents == NULL) &&
+		    (doname_it)) {
+			if (makefile_path == NULL) {
+				add_dir_to_path(".",
+						&makefile_path,
+						-1);
+#ifdef SUN5_0
+				add_dir_to_path(NOCATGETS("/usr/share/lib/make"),
+						&makefile_path,
+						-1);
+				add_dir_to_path(NOCATGETS("/etc/default"),
+						&makefile_path,
+						-1);
+#elif defined(HP_UX)
+                		findrundir_err = avo_find_run_dir(&run_dir);
+                		if (! findrundir_err) {
+                        		(void) sprintf(makerules_dir, NOCATGETS("%s/../share/lib/make"), run_dir);
+					add_dir_to_path(makerules_dir,
+							&makefile_path,
+							-1);
+                		}
+
+				add_dir_to_path(NOCATGETS("/opt/SUNWspro/share/lib/make"),
+						&makefile_path,
+						-1);
+				add_dir_to_path(NOCATGETS("/usr/share/lib/make"),
+						&makefile_path,
+						-1);
+#elif defined(linux)
+                		findrundir_err = avo_find_run_dir(&run_dir);
+                		if (! findrundir_err) {
+                        		(void) sprintf(makerules_dir, NOCATGETS("%s/../lib"), run_dir);
+					add_dir_to_path(makerules_dir,
+							&makefile_path,
+							-1);
+                		}
+
+				add_dir_to_path(NOCATGETS("/usr/SUNWspro/lib"),
+						&makefile_path,
+						-1);
+				add_dir_to_path(NOCATGETS("/opt/SUNWspro/share/lib/make"),
+						&makefile_path,
+						-1);
+				add_dir_to_path(NOCATGETS("/usr/share/lib/make"),
+						&makefile_path,
+						-1);
+#else
+				add_dir_to_path(NOCATGETS("/usr/include/make"),
+						&makefile_path,
+						-1);
+#endif
+			}
+			save_makefile_type = makefile_type;
+			makefile_type = reading_nothing;
+			if (doname(makefile_name, true, false) == build_dont_know) {
+				/* Try normalized filename */
+				string_start=get_wstring(makefile_name->string_mb);
+				for (string_end=string_start+1; *string_end != NULL; string_end++);
+				normalized_makefile_name=normalize_name(string_start, string_end - string_start);
+				if ((strcmp(makefile_name->string_mb, normalized_makefile_name->string_mb) == 0) || 
+					(doname(normalized_makefile_name, true, false) == build_dont_know)) {
+					n = access_vroot(makefile_name->string_mb,
+						 4,
+						 chase_path ?
+						 makefile_path : NULL,
+						 VROOT_DEFAULT);
+					if (n == 0) {
+						get_vroot_path((char **) NULL,
+						       &path,
+						       (char **) NULL);
+						if ((path[0] == (int) period_char) &&
+						    (path[1] == (int) slash_char)) {
+							path += 2;
+						}
+						MBSTOWCS(wcs_buffer, path);
+						makefile_name = GETNAME(wcs_buffer,
+								FIND_LENGTH);
+					}
+				}
+				retmem(string_start);
+				/* 
+				 * Commented out: retmem_mb(normalized_makefile_name->string_mb);
+				 * We have to return this memory, but it seems to trigger a bug
+				 * in dmake or in Sun C++ 5.7 compiler (it works ok if this code
+				 * is compiled using Sun C++ 5.6).
+				 */
+				// retmem_mb(normalized_makefile_name->string_mb); 
+			}
+			makefile_type = save_makefile_type;
+		}
+		source->string.free_after_use = false;
+		source->previous = NULL;
+		source->already_expanded = false;
+		/* Lock the file for read, but not when -n. */
+		if (lock_makefile && 
+		    !do_not_exec_rule) {
+
+			 make_state_lockfile = getmem(strlen(make_state->string_mb) + strlen(NOCATGETS(".lock")) + 1);
+			 (void) sprintf(make_state_lockfile,
+						NOCATGETS("%s.lock"),
+						make_state->string_mb);
+			(void) file_lock(make_state->string_mb,
+					 make_state_lockfile,
+					 (int *) &make_state_locked,
+					 0);
+			if(!make_state_locked) {
+				printf(NOCATGETS("-- NO LOCKING for read\n"));
+				retmem_mb(make_state_lockfile);
+				make_state_lockfile = 0;
+				return failed;
+			}
+		}
+		if (makefile->body.makefile.contents == NULL) {
+			save_makefile_type = makefile_type;
+			makefile_type = reading_nothing;
+			if ((doname_it) &&
+			    (doname(makefile_name, true, false) == build_failed)) {
+				if (complain) {
+					(void) fprintf(stderr,
+#ifdef DISTRIBUTED
+						       catgets(catd, 1, 67, "dmake: Couldn't dmake `%s'\n"),
+#else
+						       catgets(catd, 1, 237, "make: Couldn't make `%s'\n"),
+#endif
+						       makefile_name->string_mb);
+				}
+				max_include_depth--;
+				makefile_type = save_makefile_type;
+				return failed;
+			}
+			makefile_type = save_makefile_type;
+			//
+			// Before calling exists() make sure that we have the right timestamp
+			//
+			makefile_name->stat.time = file_no_time;
+
+			if (exists(makefile_name) == file_doesnt_exist) {
+				if (complain ||
+				    (makefile_name->stat.stat_errno != ENOENT)) {
+					if (must_exist) {
+						fatal(catgets(catd, 1, 68, "Can't find `%s': %s"),
+						      makefile_name->string_mb,
+						      errmsg(makefile_name->
+							     stat.stat_errno));
+					} else {
+						warning(catgets(catd, 1, 69, "Can't find `%s': %s"),
+							makefile_name->string_mb,
+							errmsg(makefile_name->
+							       stat.stat_errno));
+					}
+				}
+				max_include_depth--;
+				if(make_state_locked && (make_state_lockfile != NULL)) {
+					(void) unlink(make_state_lockfile);
+					retmem_mb(make_state_lockfile);
+					make_state_lockfile = NULL;
+					make_state_locked = false;
+				}
+				retmem(wcb);
+				retmem_mb((char *)source);
+				return failed;
+			}
+			/*
+			 * These values are the size and bytes of
+			 * the MULTI-BYTE makefile.
+			 */
+			orig_makefile->body.makefile.size =
+			  makefile->body.makefile.size =
+			    source->bytes_left_in_file =
+			      makefile_name->stat.size;
+			if (report_file) {
+				for (dpp = &makefiles_used;
+				     *dpp != NULL;
+				     dpp = &(*dpp)->next);
+				dp = ALLOC(Dependency);
+				dp->next = NULL;
+				dp->name = makefile_name;
+				dp->automatic = false;
+				dp->stale = false;
+				dp->built = false;
+				*dpp = dp;
+			}
+			source->fd = open_vroot(makefile_name->string_mb,
+						O_RDONLY,
+						0,
+						NULL,
+						VROOT_DEFAULT);
+			if (source->fd < 0) {
+				if (complain || (errno != ENOENT)) {
+					if (must_exist) {
+						fatal(catgets(catd, 1, 70, "Can't open `%s': %s"),
+						      makefile_name->string_mb,
+						      errmsg(errno));
+					} else {
+						warning(catgets(catd, 1, 71, "Can't open `%s': %s"),
+							makefile_name->string_mb,
+							errmsg(errno));
+					}
+				}
+				max_include_depth--;
+				return failed;
+			}
+			(void) fcntl(source->fd, F_SETFD, 1);
+			orig_makefile->body.makefile.contents =
+			  makefile->body.makefile.contents =
+			    source->string.text.p =
+			      source->string.buffer.start =
+				ALLOC_WC((int) (makefile_name->stat.size + 2));
+			if (makefile_type == reading_cpp_file) {
+				forget_after_parse = true;
+			}
+			source->string.text.end = source->string.text.p;
+			source->string.buffer.end =
+			  source->string.text.p + makefile_name->stat.size;
+		} else {
+			/* Do we ever reach here? */
+			source->fd = -1;
+			source->string.text.p =
+			  source->string.buffer.start =
+			    makefile->body.makefile.contents;
+			source->string.text.end =
+			  source->string.buffer.end =
+			    source->string.text.p + makefile->body.makefile.size;
+			source->bytes_left_in_file =
+			  makefile->body.makefile.size;
+		}
+		file_being_read = wcb;
+	} else {
+		char		*stdin_text_p;
+		char		*stdin_text_end;
+		char		*stdin_buffer_start;
+		char		*stdin_buffer_end;
+		char		*p_mb;
+		int		num_mb_chars;
+		size_t		num_wc_chars;
+
+		MBSTOWCS(wcs_buffer, NOCATGETS("Standard in"));
+		makefile_name = GETNAME(wcs_buffer, FIND_LENGTH);
+		/*
+		 * Memory to read standard in, then convert it
+		 * to wide char strings.
+		 */
+		stdin_buffer_start =
+		  stdin_text_p = getmem(length = 1024);
+		stdin_buffer_end = stdin_text_p + length;
+		MBSTOWCS(wcs_buffer, NOCATGETS("standard input"));
+		file_being_read = (wchar_t *) wsdup(wcs_buffer);
+		line_number = 0;
+		while ((n = read(fileno(stdin),
+				 stdin_text_p,
+				 length)) > 0) {
+			length -= n;
+			stdin_text_p += n;
+			if (length == 0) {
+				p_mb = getmem(length = 1024 +
+					      (stdin_buffer_end -
+					       stdin_buffer_start));
+				(void) strncpy(p_mb,
+					       stdin_buffer_start,
+					       (stdin_buffer_end -
+					        stdin_buffer_start));
+				retmem_mb(stdin_buffer_start);
+				stdin_text_p = p_mb +
+				  (stdin_buffer_end - stdin_buffer_start);
+				stdin_buffer_start = p_mb;
+				stdin_buffer_end =
+				  stdin_buffer_start + length;
+				length = 1024;
+			}
+		}
+		if (n < 0) {
+			fatal(catgets(catd, 1, 72, "Error reading standard input: %s"),
+			      errmsg(errno));
+		}
+		stdin_text_p = stdin_buffer_start;
+		stdin_text_end = stdin_buffer_end - length;
+		num_mb_chars = stdin_text_end - stdin_text_p;
+
+		/*
+		 * Now, convert the sequence of multibyte chars into
+		 * a sequence of corresponding wide character codes.
+		 */
+		source->string.free_after_use = false;
+		source->previous = NULL;
+		source->bytes_left_in_file = 0;
+		source->fd = -1;
+		source->already_expanded = false;
+		source->string.buffer.start =
+		  source->string.text.p = ALLOC_WC(num_mb_chars + 1);
+		source->string.buffer.end =
+		    source->string.text.p + num_mb_chars;
+		num_wc_chars = mbstowcs(source->string.text.p,
+					stdin_text_p,
+					num_mb_chars);
+		if ((int) num_wc_chars >= 0) {
+			source->string.text.end =
+			  source->string.text.p + num_wc_chars;
+		}
+		(void) retmem_mb(stdin_text_p);
+	}
+	line_number = 1;
+	if (trace_reader) {
+		(void) printf(catgets(catd, 1, 73, ">>>>>>>>>>>>>>>> Reading makefile %s\n"),
+			      makefile_name->string_mb);
+	}
+	parse_makefile(makefile_name, source);
+	if (trace_reader) {
+		(void) printf(catgets(catd, 1, 74, ">>>>>>>>>>>>>>>> End of makefile %s\n"),
+			      makefile_name->string_mb);
+	}
+#ifdef NSE
+	if (report_file && (previous_current_makefile[0] != NULL)) {
+		wscpy(current_makefile, previous_current_makefile);
+	}
+#endif
+	if(file_being_read) {
+		retmem(file_being_read);
+	}
+	file_being_read = previous_file_being_read;
+	line_number = previous_line_number;
+	makefile_type = reading_nothing;
+	max_include_depth--;
+	if (make_state_locked) {
+		/* Unlock .make.state. */
+		unlink(make_state_lockfile);
+		make_state_locked = false;
+		retmem_mb(make_state_lockfile);
+	}
+	if (forget_after_parse) {
+		retmem(makefile->body.makefile.contents);
+		makefile->body.makefile.contents = NULL;
+	}
+	retmem_mb((char *)source);
+	return succeeded;
+}
+
+/*
+ *	parse_makefile(true_makefile_name, source)
+ *
+ *	Strings are read from Sources.
+ *	When macros are found, their values are represented by a
+ *	Source that is pushed on a stack. At end of string
+ *	(that is returned from GET_CHAR() as 0), the block is popped.
+ *
+ *	Parameters:
+ *		true_makefile_name	The name of makefile we are parsing
+ *		source			The source block to read from
+ *
+ *	Global variables used:
+ *		do_not_exec_rule Is -n on?
+ *		line_number	The number of the current makefile line
+ *		makefile_type	What kind of makefile are we reading?
+ *		empty_name	The Name ""
+ */
+static void
+parse_makefile(register Name true_makefile_name, register Source source)
+{
+/*
+	char			mb_buffer[MB_LEN_MAX];
+ */
+	register wchar_t	*source_p;
+	register wchar_t	*source_end;
+	register wchar_t	*string_start;
+	wchar_t			*string_end;
+	register Boolean	macro_seen_in_string;
+	Boolean			append;
+	String_rec		name_string;
+	wchar_t			name_buffer[STRING_BUFFER_LENGTH];
+	register int		distance;
+	register int		paren_count;
+	int			brace_count;
+	int			char_number;
+	Cmd_line		command;
+	Cmd_line		command_tail;
+	Name			macro_value;
+
+	Name_vector_rec		target;
+	Name_vector_rec		depes;
+	Name_vector_rec		extra_name_vector;
+	Name_vector		current_names;
+	Name_vector		extra_names = &extra_name_vector;
+	Name_vector		nvp;
+	Boolean			target_group_seen;
+
+	register Reader_state   state;
+	register Reader_state   on_eoln_state;
+	register Separator	separator;
+
+	wchar_t                 buffer[4 * STRING_BUFFER_LENGTH];
+	Source			extrap;
+
+	Boolean                 save_do_not_exec_rule = do_not_exec_rule;
+	Name                    makefile_name;
+
+	static Name		sh_name;
+	static Name		shell_name;
+	int			i;
+
+	static wchar_t		include_space[10];
+	static wchar_t		include_tab[10];
+	int			tmp_bytes_left_in_string;
+	Boolean			tmp_maybe_include = false;
+	int    			emptycount = 0;
+	Boolean			first_target;
+
+	String_rec		include_name;
+	wchar_t			include_buffer[STRING_BUFFER_LENGTH];
+
+	target.next = depes.next = NULL;
+	/* Move some values from their struct to register declared locals */
+	CACHE_SOURCE(0);
+
+ start_new_line:
+	/*
+	 * Read whitespace on old line. Leave pointer on first char on
+	 * next line.
+	 */
+	first_target = true;
+	on_eoln_state = exit_state;
+/*
+	for (WCTOMB(mb_buffer, GET_CHAR());
+	     1;
+	     source_p++, WCTOMB(mb_buffer, GET_CHAR()))
+		switch (mb_buffer[0]) {
+ */
+	for (char_number=0; 1; source_p++,char_number++) switch (GET_CHAR()) {
+	case nul_char:
+		/* End of this string. Pop it and return to the previous one */
+		GET_NEXT_BLOCK(source);
+		source_p--;
+		if (source == NULL) {
+			GOTO_STATE(on_eoln_state);
+		}
+		break;
+	case newline_char:
+	end_of_line:
+		source_p++;
+		if (source->fd >= 0) {
+			line_number++;
+		}
+		switch (GET_CHAR()) {
+		case nul_char:
+			GET_NEXT_BLOCK(source);
+			if (source == NULL) {
+				GOTO_STATE(on_eoln_state);
+			}
+			/* Go back to the top of this loop */
+			goto start_new_line;
+		case newline_char:
+		case numbersign_char:
+		case dollar_char:
+		case space_char:
+		case tab_char:
+			/*
+			 * Go back to the top of this loop since the
+			 * new line does not start with a regular char.
+			 */
+			goto start_new_line;
+		default:
+			/* We found the first proper char on the new line */
+			goto start_new_line_no_skip;
+		}
+	case space_char:
+		if (char_number == 0)
+			line_started_with_space=line_number;
+	case tab_char:
+		/* Whitespace. Just keep going in this loop */
+		break;
+	case numbersign_char:
+		/* Comment. Skip over it */
+		for (; 1; source_p++) {
+			switch (GET_CHAR()) {
+			case nul_char:
+				GET_NEXT_BLOCK_NOCHK(source);
+				if (source == NULL) {
+					GOTO_STATE(on_eoln_state);
+				}
+				if (source->error_converting) {
+				// Illegal byte sequence - skip its first byte
+					source->inp_buf_ptr++;
+				}
+				source_p--;
+				break;
+			case backslash_char:
+				/* Comments can be continued */
+				if (*++source_p == (int) nul_char) {
+					GET_NEXT_BLOCK_NOCHK(source);
+					if (source == NULL) {
+						GOTO_STATE(on_eoln_state);
+					}
+					if (source->error_converting) {
+					// Illegal byte sequence - skip its first byte
+						source->inp_buf_ptr++;
+						source_p--;
+						break;
+					}
+				}
+				if(*source_p == (int) newline_char) {
+					if (source->fd >= 0) {
+						line_number++;
+					}
+				}
+				break;
+			case newline_char:
+				/*
+				 * After we skip the comment we go to
+				 * the end of line handler since end of
+				 * line terminates comments.
+				 */
+				goto end_of_line;
+			}
+		}
+	case dollar_char:
+		/* Macro reference */
+		if (source->already_expanded) {
+			/*
+			 * If we are reading from the expansion of a
+			 * macro we already expanded everything enough.
+			 */
+			goto start_new_line_no_skip;
+		}
+		/*
+		 * Expand the value and push the Source on the stack of
+		 * things being read.
+		 */
+		source_p++;
+		UNCACHE_SOURCE();
+		{
+			Source t = (Source) alloca((int) sizeof (Source_rec));
+			source = push_macro_value(t,
+						  buffer,
+						  sizeof buffer,
+						  source);
+		}
+		CACHE_SOURCE(1);
+		break;
+	default:
+		/* We found the first proper char on the new line */
+		goto start_new_line_no_skip;
+	}
+
+	/*
+	 * We found the first normal char (one that starts an identifier)
+	 * on the newline.
+	 */
+start_new_line_no_skip:
+	/* Inspect that first char to see if it maybe is special anyway */
+	switch (GET_CHAR()) {
+	case nul_char:
+		GET_NEXT_BLOCK(source);
+		if (source == NULL) {
+			GOTO_STATE(on_eoln_state);
+		}
+		goto start_new_line_no_skip;
+	case newline_char:
+		/* Just in case */
+		goto start_new_line;
+	case exclam_char:
+		/* Evaluate the line before it is read */
+		string_start = source_p + 1;
+		macro_seen_in_string = false;
+		/* Stuff the line in a string so we can eval it. */
+		for (; 1; source_p++) {
+			switch (GET_CHAR()) {
+			case newline_char:
+				goto eoln_1;
+			case nul_char:
+				if (source->fd > 0) {
+					if (!macro_seen_in_string) {
+						macro_seen_in_string = true;
+						INIT_STRING_FROM_STACK(
+						      name_string, name_buffer);
+					}
+					append_string(string_start,
+						      &name_string,
+						      source_p - string_start);
+					GET_NEXT_BLOCK(source);
+					string_start = source_p;
+					source_p--;
+					break;
+				}
+			eoln_1:
+				if (!macro_seen_in_string) {
+					INIT_STRING_FROM_STACK(name_string,
+							       name_buffer);
+				}
+				append_string(string_start,
+					      &name_string,
+					      source_p - string_start);
+				extrap = (Source)
+				  alloca((int) sizeof (Source_rec));
+				extrap->string.buffer.start = NULL;
+				extrap->inp_buf =
+				  extrap->inp_buf_ptr =
+				    extrap->inp_buf_end = NULL;
+				extrap->error_converting = false;
+				if (*source_p == (int) nul_char) {
+					source_p++;
+				}
+				/* Eval the macro */
+				expand_value(GETNAME(name_string.buffer.start,
+						     FIND_LENGTH),
+					     &extrap->string,
+					     false);
+				if (name_string.free_after_use) {
+					retmem(name_string.buffer.start);
+				}
+				UNCACHE_SOURCE();
+				extrap->string.text.p =
+				  extrap->string.buffer.start;
+				extrap->fd = -1;
+				/* And push the value */
+				extrap->previous = source;
+				source = extrap;
+				CACHE_SOURCE(0);
+				goto line_evald;
+			}
+		}
+	default:
+		goto line_evald;
+	}
+
+	/* We now have a line we can start reading */
+ line_evald:
+	if (source == NULL) {
+		GOTO_STATE(exit_state);
+	}
+	/* Check if this is an include command */
+	if ((makefile_type == reading_makefile) &&
+	    !source->already_expanded) {
+	    if (include_space[0] == (int) nul_char) {
+		MBSTOWCS(include_space, NOCATGETS("include "));
+		MBSTOWCS(include_tab, NOCATGETS("include\t"));
+	    }
+	    if ((IS_WEQUALN(source_p, include_space, 8)) ||
+		(IS_WEQUALN(source_p, include_tab, 8))) {
+		source_p += 7;
+		if (iswspace(*source_p)) {
+			Makefile_type save_makefile_type;
+			wchar_t		*name_start;
+			int		name_length;
+
+			/*
+			 * Yes, this is an include.
+			 * Skip spaces to get to the filename.
+			 */
+			while (iswspace(*source_p) ||
+			       (*source_p == (int) nul_char)) {
+				switch (GET_CHAR()) {
+				case nul_char:
+					GET_NEXT_BLOCK(source);
+					if (source == NULL) {
+						GOTO_STATE(on_eoln_state);
+					}
+					break;
+
+				default:
+					source_p++;
+					break;
+				}
+			}
+
+			string_start = source_p;
+			/* Find the end of the filename */
+			macro_seen_in_string = false;
+			while (!iswspace(*source_p) ||
+			       (*source_p == (int) nul_char)) {
+				switch (GET_CHAR()) {
+				case nul_char:
+					if (!macro_seen_in_string) {
+						INIT_STRING_FROM_STACK(name_string,
+								       name_buffer);
+					}
+					append_string(string_start,
+						      &name_string,
+						      source_p - string_start);
+					macro_seen_in_string = true;
+					GET_NEXT_BLOCK(source);
+					string_start = source_p;
+					if (source == NULL) {
+						GOTO_STATE(on_eoln_state);
+					}
+					break;
+
+				default:
+					source_p++;
+					break;
+				}
+			}
+
+			source->string.text.p = source_p;
+			if (macro_seen_in_string) {
+				append_string(string_start,
+					      &name_string,
+					      source_p - string_start);
+				name_start = name_string.buffer.start;
+				name_length = name_string.text.p - name_start;
+			} else {
+				name_start = string_start;
+				name_length = source_p - string_start;
+			}
+
+			/* Strip "./" from the head of the name */
+			if ((name_start[0] == (int) period_char) &&
+	    		   (name_start[1] == (int) slash_char)) {
+				name_start += 2;
+				name_length -= 2;
+			}
+			/* if include file name is surrounded by double quotes */
+			if ((name_start[0] == (int) doublequote_char) &&
+			    (name_start[name_length - 1] == (int) doublequote_char)) {
+			    	name_start += 1;
+			    	name_length -= 2;
+
+			    	/* if name does not begin with a slash char */
+			    	if (name_start[0] != (int) slash_char) {
+					if ((name_start[0] == (int) period_char) &&
+					    (name_start[1] == (int) slash_char)) {
+						name_start += 2;
+						name_length -= 2;
+					}
+
+					INIT_STRING_FROM_STACK(include_name, include_buffer);
+					APPEND_NAME(true_makefile_name,
+						      &include_name,
+						      true_makefile_name->hash.length);
+
+					wchar_t *slash = wsrchr(include_name.buffer.start, (int) slash_char);
+					if (slash != NULL) {
+						include_name.text.p = slash + 1;
+						append_string(name_start,
+							      &include_name,
+							      name_length);
+
+						name_start = include_name.buffer.start;
+						name_length = include_name.text.p - name_start; 
+					}
+				}
+			}
+
+			/* Even when we run -n we want to create makefiles */
+			do_not_exec_rule = false;
+			makefile_name = GETNAME(name_start, name_length);
+			if (makefile_name->dollar) {
+				String_rec	destination;
+				wchar_t		buffer[STRING_BUFFER_LENGTH];
+				wchar_t		*p;
+				wchar_t		*q;
+
+				INIT_STRING_FROM_STACK(destination, buffer);
+				expand_value(makefile_name,
+					     &destination,
+					     false);
+				for (p = destination.buffer.start;
+				     (*p != (int) nul_char) && iswspace(*p);
+				     p++);
+				for (q = p;
+				     (*q != (int) nul_char) && !iswspace(*q);
+				     q++);
+				makefile_name = GETNAME(p, q-p);
+				if (destination.free_after_use) {
+					retmem(destination.buffer.start);
+				}
+			}
+			source_p++;
+			UNCACHE_SOURCE();
+			/* Read the file */
+			save_makefile_type = makefile_type;
+			if (read_simple_file(makefile_name,
+					     true,
+					     true,
+					     true,
+					     false,
+					     true,
+					     false) == failed) {
+				fatal_reader(catgets(catd, 1, 75, "Read of include file `%s' failed"),
+					     makefile_name->string_mb);
+			}
+			makefile_type = save_makefile_type;
+			do_not_exec_rule = save_do_not_exec_rule;
+			CACHE_SOURCE(0);
+			goto start_new_line;
+		} else {
+			source_p -= 7;
+		}
+	    } else {
+		/* Check if the word include was split across 8K boundary. */
+		
+		tmp_bytes_left_in_string = source->string.text.end - source_p;
+		if (tmp_bytes_left_in_string < 8) {
+			tmp_maybe_include = false;
+			if (IS_WEQUALN(source_p,
+				       include_space,
+				       tmp_bytes_left_in_string)) {
+				tmp_maybe_include = true;
+			}
+			if (tmp_maybe_include) {
+				GET_NEXT_BLOCK(source);
+				tmp_maybe_include = false;
+				goto line_evald;
+			}
+		}
+	    }
+	}
+
+	/* Reset the status in preparation for the new line */
+	for (nvp = &target; nvp != NULL; nvp = nvp->next) {
+		nvp->used = 0;
+	}
+	for (nvp = &depes; nvp != NULL; nvp = nvp->next) {
+		nvp->used = 0;
+	}
+	target_group_seen = false;
+	command = command_tail = NULL;
+	macro_value = NULL;
+	append = false;
+	current_names = &target;
+	SET_STATE(scan_name_state);
+	on_eoln_state = illegal_eoln_state;
+	separator = none_seen;
+
+	/* The state machine starts here */
+ enter_state:
+	while (1) switch (state) {
+
+/****************************************************************
+ *	Scan name state
+ */
+case scan_name_state:
+	/* Scan an identifier. We skip over chars until we find a break char */
+	/* First skip white space. */
+	for (; 1; source_p++) switch (GET_CHAR()) {
+	case nul_char:
+		GET_NEXT_BLOCK(source);
+		source_p--;
+		if (source == NULL) {
+			GOTO_STATE(on_eoln_state);
+		}
+		break;
+	case newline_char:
+		/* We found the end of the line. */
+		/* Do postprocessing or return error */
+		source_p++;
+		if (source->fd >= 0) {
+			line_number++;
+		}
+		GOTO_STATE(on_eoln_state);
+	case backslash_char:
+		/* Continuation */
+		if (*++source_p == (int) nul_char) {
+			GET_NEXT_BLOCK(source);
+			if (source == NULL) {
+				GOTO_STATE(on_eoln_state);
+			}
+		}
+		if (*source_p == (int) newline_char) {
+			if (source->fd >= 0) {
+				line_number++;
+			}
+		} else {
+			source_p--;
+		}
+		break;
+	case tab_char:
+	case space_char:
+		/* Whitespace is skipped */
+		break;
+	case numbersign_char:
+		/* Comment. Skip over it */
+		for (; 1; source_p++) {
+			switch (GET_CHAR()) {
+			case nul_char:
+				GET_NEXT_BLOCK_NOCHK(source);
+				if (source == NULL) {
+					GOTO_STATE(on_eoln_state);
+				}
+				if (source->error_converting) {
+				// Illegal byte sequence - skip its first byte
+					source->inp_buf_ptr++;
+				}
+				source_p--;
+				break;
+			case backslash_char:
+				if (*++source_p == (int) nul_char) {
+					GET_NEXT_BLOCK_NOCHK(source);
+					if (source == NULL) {
+						GOTO_STATE(on_eoln_state);
+					}
+					if (source->error_converting) {
+					// Illegal byte sequence - skip its first byte
+						source->inp_buf_ptr++;
+						source_p--;
+						break;
+					}
+				}
+				if(*source_p == (int) newline_char) {
+					if (source->fd >= 0) {
+						line_number++;
+					}
+				}
+				break;
+			case newline_char:
+				source_p++;
+				if (source->fd >= 0) {
+					line_number++;
+				}
+				GOTO_STATE(on_eoln_state);
+			}
+		}
+	case dollar_char:
+		/* Macro reference. Expand and push value */
+		if (source->already_expanded) {
+			goto scan_name;
+		}
+		source_p++;
+		UNCACHE_SOURCE();
+		{
+			Source t = (Source) alloca((int) sizeof (Source_rec));
+			source = push_macro_value(t,
+						  buffer,
+						  sizeof buffer,
+						  source);
+		}
+		CACHE_SOURCE(1);
+		break;
+	default:
+		/* End of white space */
+		goto scan_name;
+	}
+
+	/* First proper identifier character */
+ scan_name:
+
+	string_start = source_p;
+	paren_count = brace_count = 0;
+	macro_seen_in_string = false;
+	resume_name_scan:
+	for (; 1; source_p++) {
+		switch (GET_CHAR()) {
+		case nul_char:
+			/* Save what we have seen so far of the identifier */
+			if (source_p != string_start) {
+				if (!macro_seen_in_string) {
+					INIT_STRING_FROM_STACK(name_string,
+							       name_buffer);
+				}
+				append_string(string_start,
+					      &name_string,
+					      source_p - string_start);
+				macro_seen_in_string = true;
+			}
+			/* Get more text to read */
+			GET_NEXT_BLOCK(source);
+			string_start = source_p;
+			source_p--;
+			if (source == NULL) {
+				GOTO_STATE(on_eoln_state);
+			}
+			break;
+		case newline_char:
+			if (paren_count > 0) {
+				fatal_reader(catgets(catd, 1, 76, "Unmatched `(' on line"));
+			}
+			if (brace_count > 0) {
+				fatal_reader(catgets(catd, 1, 77, "Unmatched `{' on line"));
+			}
+			source_p++;
+			/* Enter name */
+			current_names = enter_name(&name_string,
+						   macro_seen_in_string,
+						   string_start,
+						   source_p - 1,
+						   current_names,
+						   &extra_names,
+						   &target_group_seen);
+			first_target = false;
+			if (extra_names == NULL) {
+				extra_names = (Name_vector)
+				  alloca((int) sizeof (Name_vector_rec));
+			}
+			/* Do postprocessing or return error */
+			if (source->fd >= 0) {
+				line_number++;
+			}
+			GOTO_STATE(on_eoln_state);
+		case backslash_char:
+			/* Check if this is a quoting backslash */
+			if (!macro_seen_in_string) {
+				INIT_STRING_FROM_STACK(name_string,
+						       name_buffer);
+				macro_seen_in_string = true;
+			}
+			append_string(string_start,
+				      &name_string,
+				      source_p - string_start);
+			if (*++source_p == (int) nul_char) {
+				GET_NEXT_BLOCK(source);
+				if (source == NULL) {
+					GOTO_STATE(on_eoln_state);
+				}
+			}
+			if (*source_p == (int) newline_char) {
+				if (source->fd >= 0) {
+					line_number++;
+				}
+				*source_p = (int) space_char;
+				string_start = source_p;
+				goto resume_name_scan;
+			} else {
+				string_start = source_p;
+				break;
+			}
+			break;
+		case numbersign_char:
+			if (paren_count + brace_count > 0) {
+				break;
+			}
+			fatal_reader(catgets(catd, 1, 78, "Unexpected comment seen"));
+		case dollar_char:
+			if (source->already_expanded) {
+				break;
+			}
+			/* Save the identifier so far */
+			if (source_p != string_start) {
+				if (!macro_seen_in_string) {
+					INIT_STRING_FROM_STACK(name_string,
+							       name_buffer);
+				}
+				append_string(string_start,
+					      &name_string,
+					      source_p - string_start);
+				macro_seen_in_string = true;
+			}
+			/* Eval and push the macro */
+			source_p++;
+			UNCACHE_SOURCE();
+			{
+				Source t =
+				  (Source) alloca((int) sizeof (Source_rec));
+				source = push_macro_value(t,
+							  buffer,
+							  sizeof buffer,
+							  source);
+			}
+			CACHE_SOURCE(1);
+			string_start = source_p + 1;
+			break;
+		case parenleft_char:
+			paren_count++;
+			break;
+		case parenright_char:
+			if (--paren_count < 0) {
+				fatal_reader(catgets(catd, 1, 79, "Unmatched `)' on line"));
+			}
+			break;
+		case braceleft_char:
+			brace_count++;
+			break;
+		case braceright_char:
+			if (--brace_count < 0) {
+				fatal_reader(catgets(catd, 1, 80, "Unmatched `}' on line"));
+			}
+			break;
+		case ampersand_char:
+		case greater_char:
+		case bar_char:
+			if (paren_count + brace_count == 0) {
+				source_p++;
+			}
+			/* Fall into */
+		case tab_char:
+		case space_char:
+			if (paren_count + brace_count > 0) {
+				break;
+			}
+			current_names = enter_name(&name_string,
+						   macro_seen_in_string,
+						   string_start,
+						   source_p,
+						   current_names,
+						   &extra_names,
+						   &target_group_seen);
+			first_target = false;
+			if (extra_names == NULL) {
+				extra_names = (Name_vector)
+				  alloca((int) sizeof (Name_vector_rec));
+			}
+			goto enter_state;
+		case colon_char:
+			if (paren_count + brace_count > 0) {
+				break;
+			}
+			if (separator == conditional_seen) {
+				break;
+			}
+/** POSIX **/
+#if 0
+			if(posix) {
+			  emptycount = 0;
+			}
+#endif
+/** END POSIX **/
+			/* End of the target list. We now start reading */
+			/* dependencies or a conditional assignment */
+			if (separator != none_seen) {
+				fatal_reader(catgets(catd, 1, 81, "Extra `:', `::', or `:=' on dependency line"));
+			}
+			/* Enter the last target */
+			if ((string_start != source_p) ||
+			    macro_seen_in_string) {
+				current_names =
+				  enter_name(&name_string,
+					     macro_seen_in_string,
+					     string_start,
+					     source_p,
+					     current_names,
+					     &extra_names,
+					     &target_group_seen);
+				first_target = false;
+				if (extra_names == NULL) {
+					extra_names = (Name_vector)
+					  alloca((int)
+						 sizeof (Name_vector_rec));
+				}
+			}
+			/* Check if it is ":" "::" or ":=" */
+		scan_colon_label:
+			switch (*++source_p) {
+			case nul_char:
+				GET_NEXT_BLOCK(source);
+				source_p--;
+				if (source == NULL) {
+					GOTO_STATE(enter_dependencies_state);
+				}
+				goto scan_colon_label;
+			case equal_char:
+				if(svr4) {
+				  fatal_reader(catgets(catd, 1, 82, "syntax error"));
+				}
+				separator = conditional_seen;
+				source_p++;
+				current_names = &depes;
+				GOTO_STATE(scan_name_state);
+			case colon_char:
+				separator = two_colon;
+				source_p++;
+				break;
+			default:
+				separator = one_colon;
+			}
+			current_names = &depes;
+			on_eoln_state = enter_dependencies_state;
+			GOTO_STATE(scan_name_state);
+		case semicolon_char:
+			if (paren_count + brace_count > 0) {
+				break;
+			}
+			/* End of reading names. Start reading the rule */
+			if ((separator != one_colon) &&
+			    (separator != two_colon)) {
+				fatal_reader(catgets(catd, 1, 83, "Unexpected command seen"));
+			}
+			/* Enter the last dependency */
+			if ((string_start != source_p) ||
+			    macro_seen_in_string) {
+				current_names =
+				  enter_name(&name_string,
+					     macro_seen_in_string,
+					     string_start,
+					     source_p,
+					     current_names,
+					     &extra_names,
+					     &target_group_seen);
+				first_target = false;
+				if (extra_names == NULL) {
+					extra_names = (Name_vector)
+					  alloca((int)
+						 sizeof (Name_vector_rec));
+				}
+			}
+			source_p++;
+			/* Make sure to enter a rule even if the is */
+			/* no text here */
+			command = command_tail = ALLOC(Cmd_line);
+			command->next = NULL;
+			command->command_line = empty_name;
+			command->make_refd = false;
+			command->ignore_command_dependency = false;
+			command->assign = false;
+			command->ignore_error = false;
+			command->silent = false;
+
+			GOTO_STATE(scan_command_state);
+		case plus_char:
+			/*
+			** following code drops the target separator plus char if it starts
+			** a line.
+			*/ 
+			if(first_target && !macro_seen_in_string &&
+					source_p == string_start) {
+				for (; 1; source_p++)
+				switch (GET_CHAR()) {
+				case nul_char:
+					if (source_p != string_start) {
+						if (!macro_seen_in_string) {
+							INIT_STRING_FROM_STACK(name_string,
+									       name_buffer);
+						}
+						append_string(string_start,
+							      &name_string,
+							      source_p - string_start);
+						macro_seen_in_string = true;
+					}
+					GET_NEXT_BLOCK(source);
+					string_start = source_p;
+					source_p--;
+					if (source == NULL) {
+						GOTO_STATE(on_eoln_state);
+					}
+					break;
+				case plus_char:
+					source_p++;
+					while (*source_p == (int) nul_char) {
+						if (source_p != string_start) {
+							if (!macro_seen_in_string) {
+								INIT_STRING_FROM_STACK(name_string,
+									       name_buffer);
+							}
+							append_string(string_start,
+								      &name_string,
+								      source_p - string_start);
+							macro_seen_in_string = true;
+						}
+						GET_NEXT_BLOCK(source);
+						string_start = source_p;
+						if (source == NULL) {
+							GOTO_STATE(on_eoln_state);
+						}
+					}
+					if (*source_p == (int) tab_char ||
+							*source_p == (int) space_char) {
+						macro_seen_in_string = false;
+						string_start = source_p + 1;
+					} else {
+						goto resume_name_scan;
+					}
+					break;
+				case tab_char:
+				case space_char:
+					string_start = source_p + 1;
+					break;
+				default:
+					goto resume_name_scan;
+				}
+			}
+			if (paren_count + brace_count > 0) {
+				break;
+			}
+			/* We found "+=" construct */
+			if (source_p != string_start) {
+				/* "+" is not a break char. */
+				/* Ignore it if it is part of an identifier */
+				source_p++;
+				goto resume_name_scan;
+			}
+			/* Make sure the "+" is followed by a "=" */
+		scan_append:
+			switch (*++source_p) {
+			case nul_char:
+				if (!macro_seen_in_string) {
+					INIT_STRING_FROM_STACK(name_string,
+							       name_buffer);
+				}
+				append_string(string_start,
+					      &name_string,
+					      source_p - string_start);
+				GET_NEXT_BLOCK(source);
+				source_p--;
+				string_start = source_p;
+				if (source == NULL) {
+					GOTO_STATE(illegal_eoln_state);
+				}
+				goto scan_append;
+			case equal_char:
+				if(!svr4) {
+				  append = true;
+				} else {
+				  fatal_reader(catgets(catd, 1, 84, "Must be a separator on rules"));
+				}
+				break;
+			default:
+				/* The "+" just starts a regular name. */
+				/* Start reading that name */
+				goto resume_name_scan;
+			}
+			/* Fall into */
+		case equal_char:
+			if (paren_count + brace_count > 0) {
+				break;
+			}
+			/* We found macro assignment. */
+			/* Check if it is legal and if it is appending */
+			switch (separator) {
+			case none_seen:
+				separator = equal_seen;
+				on_eoln_state = enter_equal_state;
+				break;
+			case conditional_seen:
+				on_eoln_state = enter_conditional_state;
+				break;
+			default:
+				/* Reader must special check for "MACRO:sh=" */
+				/* notation */
+				if (sh_name == NULL) {
+					MBSTOWCS(wcs_buffer, NOCATGETS("sh"));
+					sh_name = GETNAME(wcs_buffer, FIND_LENGTH);
+					MBSTOWCS(wcs_buffer, NOCATGETS("shell"));
+					shell_name = GETNAME(wcs_buffer, FIND_LENGTH);
+				}
+
+				if (!macro_seen_in_string) {
+					INIT_STRING_FROM_STACK(name_string,
+						       name_buffer);
+				}
+				append_string(string_start,
+					      &name_string,
+					      source_p - string_start
+				);
+
+				if ( (((target.used == 1) &&
+				     (depes.used == 1) &&
+				     (depes.names[0] == sh_name)) ||
+				    ((target.used == 1) &&
+				     (depes.used == 0) &&
+				     (separator == one_colon) &&
+				     (GETNAME(name_string.buffer.start,FIND_LENGTH) == sh_name))) &&
+				    (!svr4)) {
+					String_rec	macro_name;
+					wchar_t		buffer[100];
+
+					INIT_STRING_FROM_STACK(macro_name,
+							       buffer);
+					APPEND_NAME(target.names[0],
+						      &macro_name,
+						      FIND_LENGTH);
+					append_char((int) colon_char,
+						    &macro_name);
+					APPEND_NAME(sh_name,
+						      &macro_name,
+						      FIND_LENGTH);
+					target.names[0] =
+					  GETNAME(macro_name.buffer.start,
+						  FIND_LENGTH);
+					separator = equal_seen;
+					on_eoln_state = enter_equal_state;
+					break;
+				} else if ( (((target.used == 1) &&
+					    (depes.used == 1) &&
+					    (depes.names[0] == shell_name)) ||
+					   ((target.used == 1) &&
+					    (depes.used == 0) &&
+					    (separator == one_colon) &&
+					    (GETNAME(name_string.buffer.start,FIND_LENGTH) == shell_name))) &&
+					   (!svr4)) {
+					String_rec	macro_name;
+					wchar_t		buffer[100];
+
+					INIT_STRING_FROM_STACK(macro_name,
+							       buffer);
+					APPEND_NAME(target.names[0],
+						      &macro_name,
+						      FIND_LENGTH);
+					append_char((int) colon_char,
+						    &macro_name);
+					APPEND_NAME(shell_name,
+						      &macro_name,
+						      FIND_LENGTH);
+					target.names[0] =
+					  GETNAME(macro_name.buffer.start,
+						  FIND_LENGTH);
+					separator = equal_seen;
+					on_eoln_state = enter_equal_state;
+					break;
+				} 
+				if(svr4) {
+				  fatal_reader(catgets(catd, 1, 85, "syntax error"));
+				}
+				else {
+				  fatal_reader(catgets(catd, 1, 86, "Macro assignment on dependency line"));
+				}
+			}
+			if (append) {
+				source_p--;
+			}
+			/* Enter the macro name */
+			if ((string_start != source_p) ||
+			    macro_seen_in_string) {
+				current_names =
+				  enter_name(&name_string,
+					     macro_seen_in_string,
+					     string_start,
+					     source_p,
+					     current_names,
+					     &extra_names,
+					     &target_group_seen);
+				first_target = false;
+				if (extra_names == NULL) {
+					extra_names = (Name_vector)
+					  alloca((int)
+						 sizeof (Name_vector_rec));
+				}
+			}
+			if (append) {
+				source_p++;
+			}
+			macro_value = NULL;
+			source_p++;
+			distance = 0;
+			/* Skip whitespace to the start of the value */
+			macro_seen_in_string = false;
+			for (; 1; source_p++) {
+				switch (GET_CHAR()) {
+				case nul_char:
+					GET_NEXT_BLOCK(source);
+					source_p--;
+					if (source == NULL) {
+						GOTO_STATE(on_eoln_state);
+					}
+					break;
+				case backslash_char:
+					if (*++source_p == (int) nul_char) {
+						GET_NEXT_BLOCK(source);
+						if (source == NULL) {
+							GOTO_STATE(on_eoln_state);
+						}
+					}
+					if (*source_p != (int) newline_char) {
+						if (!macro_seen_in_string) {
+							macro_seen_in_string =
+							  true;
+							INIT_STRING_FROM_STACK(name_string,
+									       name_buffer);
+						}
+						append_char((int)
+							    backslash_char,
+							    &name_string);
+						append_char(*source_p,
+							    &name_string);
+						string_start = source_p+1;
+						goto macro_value_start;
+					} else {
+                                            if (source->fd >= 0) {
+                                            	line_number++;
+                                            }
+                                        }
+					break;
+				case newline_char:
+				case numbersign_char:
+					string_start = source_p;
+					goto macro_value_end;
+				case tab_char:
+				case space_char:
+					break;
+				default:
+					string_start = source_p;
+					goto macro_value_start;
+				}
+			}
+		macro_value_start:
+			/* Find the end of the value */
+			for (; 1; source_p++) {
+				if (distance != 0) {
+					*source_p = *(source_p + distance);
+				}
+				switch (GET_CHAR()) {
+				case nul_char:
+					if (!macro_seen_in_string) {
+						macro_seen_in_string = true;
+						INIT_STRING_FROM_STACK(name_string,
+								       name_buffer);
+					}
+					append_string(string_start,
+						      &name_string,
+						      source_p - string_start);
+					GET_NEXT_BLOCK(source);
+					string_start = source_p;
+					source_p--;
+					if (source == NULL) {
+						GOTO_STATE(on_eoln_state);
+					}
+					break;
+				case backslash_char:
+					source_p++;
+					if (distance != 0) {
+						*source_p =
+						  *(source_p + distance);
+					}
+					if (*source_p == (int) nul_char) {
+						if (!macro_seen_in_string) {
+							macro_seen_in_string =
+							  true;
+							INIT_STRING_FROM_STACK(name_string,
+									       name_buffer);
+						}
+
+/*  BID_1225561 */
+						*(source_p - 1) = (int) space_char;
+						append_string(string_start,
+							      &name_string,
+							      source_p -
+							      string_start - 1);
+						GET_NEXT_BLOCK(source);
+						string_start = source_p;
+						if (source == NULL) {
+							GOTO_STATE(on_eoln_state);
+						}
+						if (distance != 0) {
+							*source_p =
+							  *(source_p +
+							    distance);
+						}
+						if (*source_p == (int) newline_char) {
+							append_char((int) space_char, &name_string);
+						} else {
+							append_char((int) backslash_char, &name_string);
+						}
+/****************/
+					}
+					if (*source_p == (int) newline_char) {
+						source_p--;
+						line_number++;
+						distance++;
+						*source_p = (int) space_char;
+						while ((*(source_p +
+							  distance + 1) ==
+							(int) tab_char) ||
+						       (*(source_p +
+							  distance + 1) ==
+							(int) space_char)) {
+							distance++;
+						}
+					}
+					break;
+				case newline_char:
+				case numbersign_char:
+					goto macro_value_end;
+				}
+			}
+		macro_value_end:
+			/* Complete the value in the string */
+			if (!macro_seen_in_string) {
+				macro_seen_in_string = true;
+				INIT_STRING_FROM_STACK(name_string,
+						       name_buffer);
+			}
+			append_string(string_start,
+				      &name_string,
+				      source_p - string_start);
+			if (name_string.buffer.start != name_string.text.p) {
+					macro_value =
+					  GETNAME(name_string.buffer.start,
+						  FIND_LENGTH);
+				}
+			if (name_string.free_after_use) {
+				retmem(name_string.buffer.start);
+			}
+			for (; distance > 0; distance--) {
+				*source_p++ = (int) space_char;
+			}
+			GOTO_STATE(on_eoln_state);
+		}
+	}
+
+/****************************************************************
+ *	enter dependencies state
+ */
+ case enter_dependencies_state:
+ enter_dependencies_label:
+/* Expects pointer on first non whitespace char after last dependency. (On */
+/* next line.) We end up here after having read a "targets : dependencies" */
+/* line. The state checks if there is a rule to read and if so dispatches */
+/* to scan_command_state scan_command_state reads one rule line and the */
+/* returns here */
+
+	/* First check if the first char on the next line is special */
+	switch (GET_CHAR()) {
+	case nul_char:
+		GET_NEXT_BLOCK(source);
+		if (source == NULL) {
+			break;
+		}
+		goto enter_dependencies_label;
+	case exclam_char:
+		/* The line should be evaluate before it is read */
+		macro_seen_in_string = false;
+		string_start = source_p + 1;
+		for (; 1; source_p++) {
+			switch (GET_CHAR()) {
+			case newline_char:
+				goto eoln_2;
+			case nul_char:
+				if (source->fd > 0) {
+					if (!macro_seen_in_string) {
+						macro_seen_in_string = true;
+						INIT_STRING_FROM_STACK(name_string,
+								       name_buffer);
+					}
+					append_string(string_start,
+						      &name_string,
+						      source_p - string_start);
+					GET_NEXT_BLOCK(source);
+					string_start = source_p;
+					source_p--;
+					break;
+				}
+			eoln_2:
+				if (!macro_seen_in_string) {
+					INIT_STRING_FROM_STACK(name_string,
+							       name_buffer);
+				}
+				append_string(string_start,
+					      &name_string,
+					      source_p - string_start);
+				extrap = (Source)
+				  alloca((int) sizeof (Source_rec));
+				extrap->string.buffer.start = NULL;
+				extrap->inp_buf =
+				  extrap->inp_buf_ptr =
+				    extrap->inp_buf_end = NULL;
+				extrap->error_converting = false;
+				expand_value(GETNAME(name_string.buffer.start,
+						     FIND_LENGTH),
+					     &extrap->string,
+					     false);
+				if (name_string.free_after_use) {
+					retmem(name_string.buffer.start);
+				}
+				UNCACHE_SOURCE();
+				extrap->string.text.p =
+				  extrap->string.buffer.start;
+				extrap->fd = -1;
+				extrap->previous = source;
+				source = extrap;
+				CACHE_SOURCE(0);
+				goto enter_dependencies_label;
+			}
+		}
+	case dollar_char:
+		if (source->already_expanded) {
+			break;
+		}
+		source_p++;
+		UNCACHE_SOURCE();
+		{
+			Source t = (Source) alloca((int) sizeof (Source_rec));
+			source = push_macro_value(t,
+						  buffer,
+						  sizeof buffer,
+						  source);
+		}
+		CACHE_SOURCE(0);
+		goto enter_dependencies_label;
+	case numbersign_char:
+		if (makefile_type != reading_makefile) {
+			source_p++;
+			GOTO_STATE(scan_command_state);
+		}
+		for (; 1; source_p++) {
+			switch (GET_CHAR()) {
+			case nul_char:
+				GET_NEXT_BLOCK_NOCHK(source);
+				if (source == NULL) {
+					GOTO_STATE(on_eoln_state);
+				}
+				if (source->error_converting) {
+				// Illegal byte sequence - skip its first byte
+					source->inp_buf_ptr++;
+				}
+				source_p--;
+				break;
+			case backslash_char:
+				if (*++source_p == (int) nul_char) {
+					GET_NEXT_BLOCK_NOCHK(source);
+					if (source == NULL) {
+						GOTO_STATE(on_eoln_state);
+					}
+					if (source->error_converting) {
+					// Illegal byte sequence - skip its first byte
+						source->inp_buf_ptr++;
+						source_p--;
+						break;
+					}
+				}
+				if(*source_p == (int) newline_char) {
+					if (source->fd >= 0) {
+						line_number++;
+					}
+				}
+				break;
+			case newline_char:
+				source_p++;
+				if (source->fd >= 0) {
+					line_number++;
+				}
+				goto enter_dependencies_label;
+			}
+		}
+
+	case tab_char:
+		GOTO_STATE(scan_command_state);
+	}
+
+	/* We read all the command lines for the target/dependency line. */
+	/* Enter the stuff */
+	enter_target_groups_and_dependencies( &target, &depes, command, 
+					     separator, target_group_seen);
+
+	goto start_new_line;
+
+/****************************************************************
+ *	scan command state
+ */
+case scan_command_state:
+	/* We need to read one rule line. Do that and return to */
+	/* the enter dependencies state */
+	string_start = source_p;
+	macro_seen_in_string = false;
+	for (; 1; source_p++) {
+		switch (GET_CHAR()) {
+		case backslash_char:
+			if (!macro_seen_in_string) {
+				INIT_STRING_FROM_STACK(name_string,
+						       name_buffer);
+			}
+			append_string(string_start,
+				      &name_string,
+				      source_p - string_start);
+			macro_seen_in_string = true;
+			if (*++source_p == (int) nul_char) {
+				GET_NEXT_BLOCK(source);
+				if (source == NULL) {
+					string_start = source_p;
+					goto command_newline;
+				}
+			}
+			append_char((int) backslash_char, &name_string);
+			append_char(*source_p, &name_string);
+			if (*source_p == (int) newline_char) {
+				if (source->fd >= 0) {
+					line_number++;
+				}
+				if (*++source_p == (int) nul_char) {
+					GET_NEXT_BLOCK(source);
+					if (source == NULL) {
+						string_start = source_p;
+						goto command_newline;
+					}
+				}
+				if (*source_p == (int) tab_char) {
+					source_p++;
+				}
+			} else {
+				if (*++source_p == (int) nul_char) {
+					GET_NEXT_BLOCK(source);
+					if (source == NULL) {
+						string_start = source_p;
+						goto command_newline;
+					}
+				}
+			}
+			string_start = source_p;
+			if ((*source_p == (int) newline_char) ||
+			    (*source_p == (int) backslash_char) ||
+			    (*source_p == (int) nul_char)) {
+				source_p--;
+			}
+			break;
+		case newline_char:
+		command_newline:
+			if ((string_start != source_p) ||
+			    macro_seen_in_string) {
+				if (macro_seen_in_string) {
+					append_string(string_start,
+						      &name_string,
+						      source_p - string_start);
+					string_start =
+					  name_string.buffer.start;
+					string_end = name_string.text.p;
+				} else {
+					string_end = source_p;
+				}
+				while ((*string_start != (int) newline_char) &&
+				       iswspace(*string_start)){
+					string_start++;
+				}
+				if ((string_end > string_start) ||
+				    (makefile_type == reading_statefile)) {
+					if (command_tail == NULL) {
+						command =
+						  command_tail =
+						    ALLOC(Cmd_line);
+					} else {
+						command_tail->next =
+						  ALLOC(Cmd_line);
+						command_tail =
+						  command_tail->next;
+					}
+					command_tail->next = NULL;
+					command_tail->make_refd = false;
+					command_tail->ignore_command_dependency = false;
+					command_tail->assign = false;
+					command_tail->ignore_error = false;
+					command_tail->silent = false;
+					command_tail->command_line =
+					  GETNAME(string_start,
+						  string_end - string_start);
+					if (macro_seen_in_string &&
+					    name_string.free_after_use) {
+						retmem(name_string.
+						       buffer.start);
+					}
+				}
+			}
+			do {
+				if ((source != NULL) && (source->fd >= 0)) {
+					line_number++;
+				}
+				if ((source != NULL) &&
+				    (*++source_p == (int) nul_char)) {
+					GET_NEXT_BLOCK(source);
+					if (source == NULL) {
+						GOTO_STATE(on_eoln_state);
+					}
+				}
+			} while (*source_p == (int) newline_char);
+
+			GOTO_STATE(enter_dependencies_state);
+		case nul_char:
+			if (!macro_seen_in_string) {
+				INIT_STRING_FROM_STACK(name_string,
+						       name_buffer);
+			}
+			append_string(string_start,
+				      &name_string,
+				      source_p - string_start);
+			macro_seen_in_string = true;
+			GET_NEXT_BLOCK(source);
+			string_start = source_p;
+			source_p--;
+			if (source == NULL) {
+				GOTO_STATE(enter_dependencies_state);
+			}
+			break;
+		}
+	}
+
+/****************************************************************
+ *	enter equal state
+ */
+case enter_equal_state:
+	if (target.used != 1) {
+		GOTO_STATE(poorly_formed_macro_state);
+	}
+	enter_equal(target.names[0], macro_value, append);
+	goto start_new_line;
+
+/****************************************************************
+ *	enter conditional state
+ */
+case enter_conditional_state:
+	if (depes.used != 1) {
+		GOTO_STATE(poorly_formed_macro_state);
+	}
+	for (nvp = &target; nvp != NULL; nvp = nvp->next) {
+		for (i = 0; i < nvp->used; i++) {
+			enter_conditional(nvp->names[i],
+					  depes.names[0],
+					  macro_value,
+					  append);
+		}
+	}
+	goto start_new_line;
+
+/****************************************************************
+ *	Error states
+ */
+case illegal_bytes_state:
+	fatal_reader(catgets(catd, 1, 340, "Invalid byte sequence"));
+case illegal_eoln_state:
+	if (line_number > 1) {
+		if (line_started_with_space == (line_number - 1)) {
+			line_number--;
+			fatal_reader(catgets(catd, 1, 90, "Unexpected end of line seen\n\t*** missing separator (did you mean TAB instead of 8 spaces?)"));
+		}
+	}
+	fatal_reader(catgets(catd, 1, 87, "Unexpected end of line seen"));
+case poorly_formed_macro_state:
+	fatal_reader(catgets(catd, 1, 88, "Badly formed macro assignment"));
+case exit_state:
+	return;
+default:
+	fatal_reader(catgets(catd, 1, 89, "Internal error. Unknown reader state"));
+}
+}
+
+/*
+ *	push_macro_value(bp, buffer, size, source)
+ *
+ *	Macro and function that evaluates one macro
+ *	and makes the reader read from the value of it
+ *
+ *	Return value:
+ *				The source block to read the macro from
+ *
+ *	Parameters:
+ *		bp		The new source block to fill in
+ *		buffer		Buffer to read from
+ *		size		size of the buffer
+ *		source		The old source block
+ *
+ *	Global variables used:
+ */
+static Source
+push_macro_value(register Source bp, register wchar_t *buffer, int size, register Source source)
+{
+	bp->string.buffer.start = bp->string.text.p = buffer;
+	bp->string.text.end = NULL;
+	bp->string.buffer.end = buffer + (size/SIZEOFWCHAR_T);
+	bp->string.free_after_use = false;
+	bp->inp_buf =
+	  bp->inp_buf_ptr =
+	    bp->inp_buf_end = NULL;
+	bp->error_converting = false;
+	expand_macro(source, &bp->string, (wchar_t *) NULL, false);
+	bp->string.text.p = bp->string.buffer.start;
+
+	/* 4209588: 'make' doesn't understand a macro with whitespaces in the head as target.
+	 * strip whitespace from the begining of the macro value
+	 */
+	while (iswspace(*bp->string.text.p)) {
+		bp->string.text.p++;
+	}
+
+	bp->fd = -1;
+	bp->already_expanded = true;
+	bp->previous = source;
+	return bp;
+}
+
+/*
+ *	enter_target_groups_and_dependencies(target, depes, command, separator,
+ *					     target_group_seen)
+ *
+ *	Parameters:
+ *		target 		Structure that shows the target(s) on the line
+ *				we are currently parsing. This can looks like
+ *				target1 .. targetN : dependencies
+ *						  	commands
+ *				or
+ *				target1 + .. + targetN : dependencies
+ *							 commands
+ *		depes		Dependencies
+ *		command		Points to the command(s) to be executed for 
+ *				this target.
+ *		separator	: or :: or :=
+ *		target_group_seen	Set if we have target1 + .. + targetN
+ *		
+ *		
+ * 	After reading the command lines for a target, this routine 
+ *	is called to setup the dependencies and the commands for it.
+ * 	If the target is a % pattern or part of a target group, then 
+ *  	the appropriate routines are called.
+ */
+	
+void
+enter_target_groups_and_dependencies(Name_vector target, Name_vector depes, Cmd_line command, Separator separator, Boolean target_group_seen)
+{
+	int			i;
+	Boolean			reset= true;
+	Chain			target_group_member;
+	Percent			percent_ptr;
+
+	for (; target != NULL; target = target->next) {
+		for (i = 0; i < target->used; i++) {
+			if (target->names[i] != NULL) {
+				if (target_group_seen) {
+					target_group_member =
+					  find_target_groups(target, i, reset);
+					if(target_group_member == NULL) {
+						fatal_reader(catgets(catd, 1, 328, "Unexpected '+' on dependency line"));
+					}
+				}
+				reset = false;
+
+				/* If we saw it in the makefile it must be
+				 * a file */
+				target->names[i]->stat.is_file = true;
+				/* Make sure that we use dependencies 
+				 * entered for makefiles */
+				target->names[i]->state = build_dont_know;
+
+				/* If the target is special we delegate 
+				 * the processing */
+				if (target->names[i]->special_reader 
+				    != no_special) {
+					special_reader(target->names[i], 
+						       depes, 
+						       command);
+				}	
+				/* Check if this is a "a%b : x%y" type rule */
+				else if (target->names[i]->percent) {
+					percent_ptr = 
+					  enter_percent(target->names[i], 
+							target->target_group[i], 
+							depes, command);
+					if (target_group_seen) {
+						target_group_member->percent_member =
+						  percent_ptr;
+					}
+				} else if (target->names[i]->dollar) {
+					enter_dyntarget(target->names[i]);
+					enter_dependencies
+					  (target->names[i],
+					   target->target_group[i],
+					   depes,	
+					   command,
+					   separator);
+				} else {
+					if (target_group_seen) {
+						target_group_member->percent_member =
+						  NULL;
+					}
+				
+					enter_dependencies
+					  (target->names[i],
+					   target->target_group[i],
+					   depes,	
+					   command,
+					   separator);
+				}
+			}
+		}
+	}
+}
+				     
+
--- /dev/null	2015-05-20 11:04:11.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/common/read2.cc	2015-05-20 11:04:11.068979667 -0400
@@ -0,0 +1,1938 @@
+/*
+ * 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 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)read2.cc 1.53 06/12/12
+ */
+
+#pragma	ident	"@(#)read2.cc	1.53	06/12/12"
+
+/*
+ *	read.c
+ *
+ *	This file contains the makefile reader.
+ */
+
+/*
+ * Included files
+ */
+#include <mk/defs.h>
+#include <mksh/dosys.h>		/* sh_command2string() */
+#include <mksh/macro.h>		/* expand_value() */
+#include <mksh/misc.h>		/* retmem() */
+#include <stdarg.h>		/* va_list, va_start(), va_end() */
+
+/*
+ * Defined macros
+ */
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+static	Boolean		built_last_make_run_seen;
+
+/*
+ * File table of contents
+ */
+static	Name_vector	enter_member_name(register wchar_t *lib_start, register wchar_t *member_start, register wchar_t *string_end, Name_vector current_names, Name_vector *extra_names);
+extern	Name		normalize_name(register wchar_t *name_string, register int length);
+static	void		read_suffixes_list(register Name_vector depes);
+static	void		make_relative(wchar_t *to, wchar_t *result);
+static	void		print_rule(register Cmd_line command);
+static	void		sh_transform(Name *name, Name *value);
+
+
+/*
+ *	enter_name(string, tail_present, string_start, string_end,
+ *	      current_names, extra_names, target_group_seen)
+ *
+ *	Take one string and enter it as a name. The string is passed in
+ *	two parts. A make string and possibly a C string to append to it.
+ *	The result is stuffed in the vector current_names.
+ *	extra_names points to a vector that is used if current_names overflows.
+ *	This is allocad in the calling routine.
+ *	Here we handle the "lib.a[members]" notation.
+ *
+ *	Return value:
+ *				The name vector that was used
+ *
+ *	Parameters:
+ *		tail_present	Indicates if both C and make string was passed
+ *		string_start	C string
+ *		string_end	Pointer to char after last in C string
+ *		string		make style string with head of name
+ *		current_names	Vector to deposit the name in
+ *		extra_names	Where to get next name vector if we run out
+ *		target_group_seen Pointer to boolean that is set if "+" is seen
+ *
+ *	Global variables used:
+ *		makefile_type	When we read a report file we normalize paths
+ *		plus		Points to the Name "+"
+ */
+
+Name_vector
+enter_name(String string, Boolean tail_present, register wchar_t *string_start, register wchar_t *string_end, Name_vector current_names, Name_vector *extra_names, Boolean *target_group_seen)
+{
+	Name			name;
+	register wchar_t	*cp;
+	wchar_t			ch;
+
+	/* If we were passed a separate tail of the name we append it to the */
+	/* make string with the rest of it */
+	if (tail_present) {
+		append_string(string_start, string, string_end - string_start);
+		string_start = string->buffer.start;
+		string_end = string->text.p;
+	}
+	ch = *string_end;
+	*string_end = (int) nul_char;
+	/*
+	 * Check if there are any ( or [ that are not prefixed with $.
+	 * If there are, we have to deal with the lib.a(members) format.
+	 */
+	for (cp = (wchar_t *) wschr(string_start, (int) parenleft_char);
+	     cp != NULL;
+	     cp = (wchar_t *) wschr(cp + 1, (int) parenleft_char)) {
+		if (*(cp - 1) != (int) dollar_char) {
+			*string_end = ch;
+			return enter_member_name(string_start,
+						 cp,
+						 string_end,
+						 current_names,
+						 extra_names);
+		}
+	}
+	*string_end = ch;
+
+	if (makefile_type == reading_cpp_file) {
+		/* Remove extra ../ constructs if we are reading from a report file */
+		name = normalize_name(string_start, string_end - string_start);
+	} else {
+		/*
+		 * /tolik, fix bug 1197477/
+		 * Normalize every target name before entering.
+		 * ..//obj/a.o and ../obj//a.o are not two different targets.
+		 * There is only one target ../obj/a.o
+		 */
+		/*name = GETNAME(string_start, string_end - string_start);*/
+		name = normalize_name(string_start, string_end - string_start);
+	}
+
+	/* Internalize the name. Detect the name "+" (target group here) */
+if(current_names->used != 0 && current_names->names[current_names->used-1] == plus) {
+	if(name == plus) {
+		return current_names;
+	}
+}
+	/* If the current_names vector is full we patch in the one from */
+	/* extra_names */
+	if (current_names->used == VSIZEOF(current_names->names)) {
+		if (current_names->next != NULL) {
+			current_names = current_names->next;
+		} else {
+			current_names->next = *extra_names;
+			*extra_names = NULL;
+			current_names = current_names->next;
+			current_names->used = 0;
+			current_names->next = NULL;
+		}
+	}
+	current_names->target_group[current_names->used] = NULL;
+	current_names->names[current_names->used++] = name;
+	if (name == plus) {
+		*target_group_seen = true;
+	}
+	if (tail_present && string->free_after_use) {
+		retmem(string->buffer.start);
+	}
+	return current_names;
+}
+
+/*
+ *	enter_member_name(lib_start, member_start, string_end,
+ *		  current_names, extra_names)
+ *
+ *	A string has been found to contain member names.
+ *	(The "lib.a[members]" and "lib.a(members)" notation)
+ *	Handle it pretty much as enter_name() does for simple names.
+ *
+ *	Return value:
+ *				The name vector that was used
+ *
+ *	Parameters:
+ *		lib_start	Points to the of start of "lib.a(member.o)"
+ *		member_start	Points to "member.o" from above string.
+ *		string_end	Points to char after last of above string.
+ *		current_names	Vector to deposit the name in
+ *		extra_names	Where to get next name vector if we run out
+ *
+ *	Global variables used:
+ */
+static Name_vector
+enter_member_name(register wchar_t *lib_start, register wchar_t *member_start, register wchar_t *string_end, Name_vector current_names, Name_vector *extra_names)
+{
+	register Boolean	entry = false;
+	wchar_t			buffer[STRING_BUFFER_LENGTH];
+	Name			lib;
+	Name			member;
+	Name			name;
+	Property		prop;
+	wchar_t			*memberp;
+	wchar_t			*q;
+	register int		paren_count;
+	register Boolean	has_dollar;
+	register wchar_t	*cq;
+	Name			long_member_name = NULL;
+
+	/* Internalize the name of the library */
+	lib = GETNAME(lib_start, member_start - lib_start);
+	lib->is_member = true;
+	member_start++;
+	if (*member_start == (int) parenleft_char) {
+		/* This is really the "lib.a((entries))" format */
+		entry = true;
+		member_start++;
+	}
+	/* Move the library name to the buffer where we intend to build the */
+	/* "lib.a(member)" for each member */
+	(void) wsncpy(buffer, lib_start, member_start - lib_start);
+	memberp = buffer + (member_start-lib_start);
+	while (1) {
+		long_member_name = NULL;
+		/* Skip leading spaces */
+		for (;
+		     (member_start < string_end) && iswspace(*member_start);
+		     member_start++);
+		/* Find the end of the member name. Allow nested (). Detect $*/
+		for (cq = memberp, has_dollar = false, paren_count = 0;
+		     (member_start < string_end) &&
+		     ((*member_start != (int) parenright_char) ||
+		      (paren_count > 0)) &&
+		     !iswspace(*member_start);
+		     *cq++ = *member_start++) {
+			switch (*member_start) {
+			case parenleft_char:
+				paren_count++;
+				break;
+			case parenright_char:
+				paren_count--;
+				break;
+			case dollar_char:
+				has_dollar = true;
+			}
+		}
+		/* Internalize the member name */
+		member = GETNAME(memberp, cq - memberp);
+		*cq = 0;
+		if ((q = (wchar_t *) wsrchr(memberp, (int) slash_char)) == NULL) {
+			q = memberp;
+		}
+		if ((cq - q > (int) ar_member_name_len) &&
+		    !has_dollar) {
+			*cq++ = (int) parenright_char;
+			if (entry) {
+				*cq++ = (int) parenright_char;
+			}
+			long_member_name = GETNAME(buffer, cq - buffer);
+			cq = q + (int) ar_member_name_len;
+		}
+		*cq++ = (int) parenright_char;
+		if (entry) {
+			*cq++ = (int) parenright_char;
+		}
+		/* Internalize the "lib.a(member)" notation for this member */
+		name = GETNAME(buffer, cq - buffer);
+		name->is_member = lib->is_member;
+		if (long_member_name != NULL) {
+			prop = append_prop(name, long_member_name_prop);
+			name->has_long_member_name = true;
+			prop->body.long_member_name.member_name =
+			  long_member_name;
+		}
+		/* And add the member prop */
+		prop = append_prop(name, member_prop);
+		prop->body.member.library = lib;
+		if (entry) {
+			/* "lib.a((entry))" notation */
+			prop->body.member.entry = member;
+			prop->body.member.member = NULL;
+		} else {
+			/* "lib.a(member)" Notation */
+			prop->body.member.entry = NULL;
+			prop->body.member.member = member;
+		}
+		/* Handle overflow of current_names */
+		if (current_names->used == VSIZEOF(current_names->names)) {
+			if (current_names->next != NULL) {
+				current_names = current_names->next;
+			} else {
+				if (*extra_names == NULL) {
+					current_names =
+					  current_names->next =
+					    ALLOC(Name_vector);
+				} else {
+					current_names =
+					  current_names->next =
+					    *extra_names;
+					*extra_names = NULL;
+				}
+				current_names->used = 0;
+				current_names->next = NULL;
+			}
+		}
+		current_names->target_group[current_names->used] = NULL;
+		current_names->names[current_names->used++] = name;
+		while (iswspace(*member_start)) {
+			member_start++;
+		}
+		/* Check if there are more members */
+		if ((*member_start == (int) parenright_char) ||
+		    (member_start >= string_end)) {
+			return current_names;
+		}
+	}
+	/* NOTREACHED */
+}
+
+/*
+ *	normalize_name(name_string, length)
+ *
+ *	Take a namestring and remove redundant ../, // and ./ constructs
+ *
+ *	Return value:
+ *				The normalized name
+ *
+ *	Parameters:
+ *		name_string	Path string to normalize
+ *		length		Length of that string
+ *
+ *	Global variables used:
+ *		dot		The Name ".", compared against
+ *		dotdot		The Name "..", compared against
+ */
+Name
+normalize_name(register wchar_t *name_string, register int length)
+{
+	static Name		dotdot;
+	register wchar_t	*string = ALLOC_WC(length + 1);
+	register wchar_t	*string2;
+	register wchar_t	*cdp;
+	wchar_t			*current_component;
+	Name			name;
+	register int		count;
+
+	if (dotdot == NULL) {
+		MBSTOWCS(wcs_buffer, "..");
+		dotdot = GETNAME(wcs_buffer, FIND_LENGTH);
+	}
+
+	/*
+	 * Copy string removing ./ and //.
+	 * First strip leading ./
+	 */
+	while ((length > 1) &&
+	       (name_string[0] == (int) period_char) &&
+	       (name_string[1] == (int) slash_char)) {
+		name_string += 2;
+		length -= 2;
+		while ((length > 0) && (name_string[0] == (int) slash_char)) {
+			name_string++;
+			length--;
+		}
+	}
+	/* Then copy the rest of the string removing /./ & // */
+	cdp = string;
+	while (length > 0) {
+		if (((length > 2) &&
+		     (name_string[0] == (int) slash_char) &&
+		     (name_string[1] == (int) period_char) &&
+		     (name_string[2] == (int) slash_char)) ||
+		    ((length == 2) &&
+		     (name_string[0] == (int) slash_char) &&
+		     (name_string[1] == (int) period_char))) {
+			name_string += 2;
+			length -= 2;
+			continue;
+		}
+		if ((length > 1) &&
+		    (name_string[0] == (int) slash_char) &&
+		    (name_string[1] == (int) slash_char)) {
+			name_string++;
+			length--;
+			continue;
+		}
+		*cdp++ = *name_string++;
+		length--;
+	}
+	*cdp = (int) nul_char;
+	/*
+	 * Now scan for <name>/../ and remove such combinations iff <name>
+	 * is not another ..
+	 * Each time something is removed, the whole process is restarted.
+	 */
+removed_one:
+	name_string = string;
+	string2 = name_string;		/*save for free*/
+	current_component =
+	  cdp =
+	    string =
+	      ALLOC_WC((length = wslen(name_string)) + 1);
+	while (length > 0) {
+		if (((length > 3) &&
+		     (name_string[0] == (int) slash_char) &&
+		     (name_string[1] == (int) period_char) &&
+		     (name_string[2] == (int) period_char) &&
+		     (name_string[3] == (int) slash_char)) ||
+		    ((length == 3) &&
+		     (name_string[0] == (int) slash_char) &&
+		     (name_string[1] == (int) period_char) &&
+		     (name_string[2] == (int) period_char))) {
+			/* Positioned on the / that starts a /.. sequence */
+			if (((count = cdp - current_component) != 0) &&
+			    (exists(name = GETNAME(string, cdp - string)) > file_doesnt_exist) &&
+			    (!name->stat.is_sym_link)) {
+				name = GETNAME(current_component, count);
+				if(name != dotdot) {
+					cdp = current_component;
+					name_string += 3;
+					length -= 3;
+					if (length > 0) {
+						name_string++;	/* skip slash */
+						length--;
+						while (length > 0) {
+							*cdp++ = *name_string++;
+							length--;
+						}
+					}
+					*cdp = (int) nul_char;
+					retmem(string2);
+					goto removed_one;
+				}
+			}
+		}
+		if ((*cdp++ = *name_string++) == (int) slash_char) {
+			current_component = cdp;
+		}
+		length--;
+	}
+	*cdp = (int) nul_char;
+	if (string[0] == (int) nul_char) {
+		name = dot;
+	} else {
+		name = GETNAME(string, FIND_LENGTH);
+	}
+	retmem(string);
+	retmem(string2);
+	return name;
+}
+
+/*
+ *	find_target_groups(target_list)
+ *
+ *	If a "+" was seen when the target list was scanned we need to extract
+ *	the groups. Each target in the name vector that is a member of a
+ *	group gets a pointer to a chain of all the members stuffed in its
+ *	target_group vector slot
+ *
+ *	Parameters:
+ *		target_list	The list of targets that contains "+"
+ *
+ *	Global variables used:
+ *		plus		The Name "+", compared against
+ */
+Chain
+find_target_groups(register Name_vector target_list, register int i, Boolean reset)
+{
+	static Chain		target_group = NULL;
+	static Chain		tail_target_group = NULL;
+	static Name		*next;
+	static Boolean	clear_target_group = false;
+
+	if (reset) {
+		target_group = NULL;
+		tail_target_group = NULL;
+		clear_target_group = false;
+	}
+
+	/* Scan the list of targets */
+	/* If the previous target terminated a group */
+	/* we flush the pointer to that member chain */
+	if (clear_target_group) {
+		clear_target_group = false;
+		target_group = NULL;
+	}
+	/* Pick up a pointer to the cell with */
+	/* the next target */
+	if (i + 1 != target_list->used) {
+		next = &target_list->names[i + 1];
+	} else {
+		next = (target_list->next != NULL) ?
+		  &target_list->next->names[0] : NULL;
+	}
+	/* We have four states here :
+	 *	0:	No target group started and next element is not "+" 
+	 *		This is not interesting.
+	 *	1:	A target group is being built and the next element 
+	 *		is not "+". This terminates the group.
+	 *	2:	No target group started and the next member is "+" 
+	 *		This is the first target in a group.
+	 *	3:	A target group started and the next member is a "+" 
+	 *		The group continues.
+	 */
+	switch ((target_group ? 1 : 0) +
+		(next && (*next == plus) ?
+		 2 : 0)) {
+	      case 0:	/* Not target_group */
+		break;
+	      case 1:	/* Last group member */
+		/* We need to keep this pointer so */
+		/* we can stuff it for last member */
+		clear_target_group = true;
+		/* fall into */
+	      case 3:	/* Middle group member */
+		/* Add this target to the */
+		/* current chain */
+		tail_target_group->next = ALLOC(Chain);
+		tail_target_group = tail_target_group->next;
+		tail_target_group->next = NULL;
+		tail_target_group->name = target_list->names[i];
+		break;
+	      case 2:	/* First group member */
+		/* Start a new chain */
+		target_group = tail_target_group = ALLOC(Chain);
+		target_group->next = NULL;
+		target_group->name = target_list->names[i];
+		break;
+	}
+	/* Stuff the current chain, if any, in the */
+	/* targets group slot */
+	target_list->target_group[i] = target_group;
+	if ((next != NULL) &&
+	    (*next == plus)) {
+		*next = NULL;
+	}
+	return (tail_target_group);
+}
+
+/*
+ *	enter_dependencies(target, target_group, depes, command, separator)
+ *
+ *	Take one target and a list of dependencies and process the whole thing.
+ *	The target might be special in some sense in which case that is handled
+ *
+ *	Parameters:
+ *		target		The target we want to enter
+ *		target_group	Non-NULL if target is part of a group this time
+ *		depes		A list of dependencies for the target
+ *		command		The command the target should be entered with
+ *		separator	Indicates if this is a ":" or a "::" rule
+ *
+ *	Static variables used:
+ *		built_last_make_run_seen If the previous target was
+ *					.BUILT_LAST_MAKE_RUN we say to rewrite
+ *					the state file later on
+ *
+ *	Global variables used:
+ *		command_changed	Set to indicate if .make.state needs rewriting
+ *		default_target_to_build Set to the target if reading makefile
+ *					and this is the first regular target
+ *		force		The Name " FORCE", used with "::" targets
+ *		makefile_type	We do different things for makefile vs. report
+ *		not_auto	The Name ".NOT_AUTO", compared against
+ *		recursive_name	The Name ".RECURSIVE", compared against
+ *		temp_file_number Used to figure out when to clear stale
+ *					automatic dependencies
+ *		trace_reader	Indicates that we should echo stuff we read
+ */
+void
+enter_dependencies(register Name target, Chain target_group, register Name_vector depes, register Cmd_line command, register Separator separator)
+{
+	register int		i;
+	register Property	line;
+	Name			name;
+	Name			directory;
+	wchar_t			*namep;
+	char			*mb_namep;
+	Dependency		dp;
+	Dependency		*dpp;
+	Property		line2;
+	wchar_t			relative[MAXPATHLEN];
+	register int		recursive_state;
+	Boolean			register_as_auto;
+	Boolean			not_auto_found;
+	char			*slash;
+	Wstring			depstr;
+
+	/* Check if this is a .RECURSIVE line */
+	if ((depes->used >= 3) &&
+	    (depes->names[0] == recursive_name)) {
+#ifdef NSE
+                nse_did_recursion= true;
+#endif
+		target->has_recursive_dependency = true;
+		depes->names[0] = NULL;
+		recursive_state = 0;
+		dp = NULL;
+		dpp = &dp;
+		/* Read the dependencies. They are "<directory> <target-made>*/
+		/* <makefile>*" */
+		for (; depes != NULL; depes = depes->next) {
+			for (i = 0; i < depes->used; i++) {
+				if (depes->names[i] != NULL) {
+					switch (recursive_state++) {
+					case 0:	/* Directory */
+					{
+						depstr.init(depes->names[i]);
+						make_relative(depstr.get_string(),
+							      relative);
+						directory =
+						  GETNAME(relative,
+							  FIND_LENGTH);
+					}
+						break;
+					case 1:	/* Target */
+						name = depes->names[i];
+						break;
+					default:	/* Makefiles */
+						*dpp = ALLOC(Dependency);
+						(*dpp)->next = NULL;
+						(*dpp)->name = depes->names[i];
+						(*dpp)->automatic = false;
+						(*dpp)->stale = false;
+						(*dpp)->built = false;
+						dpp = &((*dpp)->next);
+						break;
+					}
+				}
+			}
+		}
+		/* Check if this recursion already has been reported else */
+		/* enter the recursive prop for the target */
+		/* The has_built flag is used to tell if this .RECURSIVE */
+		/* was discovered from this run (read from a tmp file) */
+		/* or was from discovered from the original .make.state */
+		/* file */
+		for (line = get_prop(target->prop, recursive_prop);
+		     line != NULL;
+		     line = get_prop(line->next, recursive_prop)) {
+			if ((line->body.recursive.directory == directory) &&
+			    (line->body.recursive.target == name)) {
+				line->body.recursive.makefiles = dp;
+				line->body.recursive.has_built = 
+				  (Boolean)
+				    (makefile_type == reading_cpp_file);
+				return;
+			}
+		}
+		line2 = append_prop(target, recursive_prop);
+		line2->body.recursive.directory = directory;
+		line2->body.recursive.target = name;
+		line2->body.recursive.makefiles = dp;
+		line2->body.recursive.has_built = 
+		    (Boolean) (makefile_type == reading_cpp_file);
+		line2->body.recursive.in_depinfo = false;
+		return;
+	}
+	/* If this is the first target that doesnt start with a "." in the */
+	/* makefile we remember that */
+	Wstring tstr(target);
+	wchar_t * wcb = tstr.get_string();
+	if ((makefile_type == reading_makefile) &&
+	    (default_target_to_build == NULL) &&
+	    ((wcb[0] != (int) period_char) ||
+	     wschr(wcb, (int) slash_char))) {
+
+/* BID 1181577: $(EMPTY_MACRO) + $(EMPTY_MACRO):
+** The target with empty name cannot be default_target_to_build
+*/
+		if (target->hash.length != 0)
+			default_target_to_build = target;
+	}
+	/* Check if the line is ":" or "::" */
+	if (makefile_type == reading_makefile) {
+		if (target->colons == no_colon) {
+			target->colons = separator;
+		} else {
+			if (target->colons != separator) {
+				fatal_reader(catgets(catd, 1, 92, ":/:: conflict for target `%s'"),
+					     target->string_mb);
+			}
+		}
+		if (target->colons == two_colon) {
+			if (depes->used == 0) {
+				/* If this is a "::" type line with no */
+				/* dependencies we add one "FRC" type */
+				/* dependency for free */
+				depes->used = 1; /* Force :: targets with no
+						  * depes to always run */
+				depes->names[0] = force;
+			}
+			/* Do not delete "::" type targets when interrupted */
+			target->stat.is_precious = true;
+			/*
+			 * Build a synthetic target "<number>%target"
+			 * for "target".
+			 */
+			mb_namep = getmem((int) (strlen(target->string_mb) + 10));
+			namep = ALLOC_WC((int) (target->hash.length + 10));
+			slash = strrchr(target->string_mb, (int) slash_char);
+			if (slash == NULL) {
+				(void) sprintf(mb_namep,
+					        "%d@%s",
+					        target->colon_splits++,
+					        target->string_mb);
+			} else {
+				*slash = 0;
+				(void) sprintf(mb_namep,
+					        "%s/%d@%s",
+					        target->string_mb,
+					        target->colon_splits++,
+					        slash + 1);
+				*slash = (int) slash_char;
+			}
+			MBSTOWCS(namep, mb_namep);
+			retmem_mb(mb_namep);
+			name = GETNAME(namep, FIND_LENGTH);
+			retmem(namep);
+			if (trace_reader) {
+				(void) printf("%s:\t", target->string_mb);
+			}
+			/* Make "target" depend on "<number>%target */
+			line2 = maybe_append_prop(target, line_prop);
+			enter_dependency(line2, name, true);
+			line2->body.line.target = target;
+			/* Put a prop on "<number>%target that makes */
+			/* appear as "target" */
+			/* when it is processed */
+			maybe_append_prop(name, target_prop)->
+			  body.target.target = target;
+			target->is_double_colon_parent = true;
+			name->is_double_colon = true;
+			name->has_target_prop = true;
+			if (trace_reader) {
+				(void) printf("\n");
+			}
+			(target = name)->stat.is_file = true;
+		}
+	}
+	/* This really is a regular dependency line. Just enter it */
+	line = maybe_append_prop(target, line_prop);
+	line->body.line.target = target;
+	/* Depending on what kind of makefile we are reading we have to */
+	/* treat things differently */
+	switch (makefile_type) {
+	case reading_makefile:
+		/* Reading regular makefile. Just notice whether this */
+		/* redefines the rule for the  target */
+		if (command != NULL) {
+			if (line->body.line.command_template != NULL) {
+				line->body.line.command_template_redefined =
+				  true;
+				if ((wcb[0] == (int) period_char) &&
+				    !wschr(wcb, (int) slash_char)) {
+					line->body.line.command_template =
+					  command;
+				}
+			} else {
+				line->body.line.command_template = command;
+			}
+		} else {
+			if ((wcb[0] == (int) period_char) &&
+			    !wschr(wcb, (int) slash_char)) {
+				line->body.line.command_template = command;
+			}
+		}
+		break;
+	case rereading_statefile:
+		/* Rereading the statefile. We only enter thing that changed */
+		/* since the previous time we read it */
+		if (!built_last_make_run_seen) {
+			for (Cmd_line next, cmd = command; cmd != NULL; cmd = next) {
+				next = cmd->next;
+				free(cmd);
+			}
+			return;
+		}
+		built_last_make_run_seen = false;
+		command_changed = true;
+		target->ran_command = true;
+	case reading_statefile:
+		/* Reading the statefile for the first time. Enter the rules */
+		/* as "Commands used" not "templates to use" */
+		if (command != NULL) {
+			for (Cmd_line next, cmd = line->body.line.command_used;
+			     cmd != NULL; cmd = next) {
+				next = cmd->next;
+				free(cmd);
+			}
+			line->body.line.command_used = command;
+		}
+	case reading_cpp_file:
+		/* Reading report file from programs that reports */
+		/* dependencies. If this is the first time the target is */
+		/* read from this reportfile we clear all old */
+		/* automatic depes */
+		if (target->temp_file_number == temp_file_number) {
+			break;
+		}
+		target->temp_file_number = temp_file_number;
+		command_changed = true;
+		if (line != NULL) {
+			for (dp = line->body.line.dependencies;
+			     dp != NULL;
+			     dp = dp->next) {
+				if (dp->automatic) {
+					dp->stale = true;
+				}
+			}
+		}
+		break;
+	default:
+		fatal_reader(catgets(catd, 1, 93, "Internal error. Unknown makefile type %d"),
+			     makefile_type);
+	}
+	/* A target may only be involved in one target group */
+	if (line->body.line.target_group != NULL) {
+		if (target_group != NULL) {
+			fatal_reader(catgets(catd, 1, 94, "Too many target groups for target `%s'"),
+				     target->string_mb);
+		}
+	} else {
+		line->body.line.target_group = target_group;
+	}
+
+	if (trace_reader) {
+		(void) printf("%s:\t", target->string_mb);
+	}
+	/* Enter the dependencies */
+	register_as_auto = BOOLEAN(makefile_type != reading_makefile);
+	not_auto_found = false;
+	for (;
+	     (depes != NULL) && !not_auto_found;
+	     depes = depes->next) {
+		for (i = 0; i < depes->used; i++) {
+			/* the dependency .NOT_AUTO signals beginning of
+			 * explicit dependancies which were put at end of
+			 * list in .make.state file - we stop entering
+			 * dependencies at this point
+			 */
+			if (depes->names[i] == not_auto) {
+				not_auto_found = true;
+				break;
+			}
+			enter_dependency(line,
+					 depes->names[i],
+					 register_as_auto);
+		}
+	}
+	if (trace_reader) {
+		(void) printf("\n");
+		print_rule(command);
+	}
+}
+
+/*
+ *	enter_dependency(line, depe, automatic)
+ *
+ *	Enter one dependency. Do not enter duplicates.
+ *
+ *	Parameters:
+ *		line		The line block that the dependeny is
+ *				entered for
+ *		depe		The dependency to enter
+ *		automatic	Used to set the field "automatic"
+ *
+ *	Global variables used:
+ *		makefile_type	We do different things for makefile vs. report
+ *		trace_reader	Indicates that we should echo stuff we read
+ *		wait_name	The Name ".WAIT", compared against
+ */
+void
+enter_dependency(Property line, register Name depe, Boolean automatic)
+{
+	register Dependency	dp;
+	register Dependency	*insert;
+
+	if (trace_reader) {
+		(void) printf("%s ", depe->string_mb);
+	}
+	/* Find the end of the list and check for duplicates */
+	for (insert = &line->body.line.dependencies, dp = *insert;
+	     dp != NULL;
+	     insert = &dp->next, dp = *insert) {
+		if ((dp->name == depe) && (depe != wait_name)) {
+			if (dp->automatic) {
+				dp->automatic = automatic;
+				if (automatic) {
+					dp->built = false;
+					depe->stat.is_file = true;
+#ifdef NSE
+				        depe->has_parent= true;
+				        depe->is_target= true;
+#endif
+				}
+			}
+			dp->stale = false;
+			return;
+		}
+	}
+	/* Insert the new dependency since we couldnt find it */
+	dp = *insert = ALLOC(Dependency);
+	dp->name = depe;
+	dp->next = NULL;
+	dp->automatic = automatic;
+	dp->stale = false;
+	dp->built = false;
+	depe->stat.is_file = true;
+#ifdef NSE
+        depe->has_parent= true;
+        depe->is_target= true;
+#endif
+
+	if ((makefile_type == reading_makefile) &&
+	    (line != NULL) &&
+	    (line->body.line.target != NULL)) {
+		line->body.line.target->has_regular_dependency = true;
+#ifdef NSE
+                line->body.line.target->is_target= true;
+#endif
+	}
+}
+
+/*
+ *	enter_percent(target, depes, command)
+ *
+ *	Enter "x%y : a%b" type lines
+ *	% patterns are stored in four parts head and tail for target and source
+ *
+ *	Parameters:
+ *		target		Left hand side of pattern
+ *		depes		The dependency list with the rh pattern
+ *		command		The command for the pattern
+ *
+ *	Global variables used:
+ *		empty_name	The Name "", compared against
+ *		percent_list	The list of all percent rules, added to
+ *		trace_reader	Indicates that we should echo stuff we read
+ */
+Percent
+enter_percent(register Name target, Chain target_group, register Name_vector depes, Cmd_line command)
+{
+	register Percent	result = ALLOC(Percent);
+	register Percent	depe;
+	register Percent	*depe_tail = &result->dependencies;
+	register Percent	*insert;
+	register wchar_t	*cp, *cp1;
+	Name_vector		nvp;
+	int			i;
+	int			pattern;
+
+	result->next = NULL;
+	result->patterns = NULL;
+	result->patterns_total = 0;
+	result->command_template = command;
+	result->being_expanded = false;
+	result->name = target;
+	result->dependencies = NULL;
+	result->target_group = target_group;
+
+	/* get patterns count */
+	Wstring wcb(target);
+	cp = wcb.get_string();
+	while (true) {
+		cp = (wchar_t *) wschr(cp, (int) percent_char);
+		if (cp != NULL) {
+			result->patterns_total++;
+			cp++;
+		} else {
+			break;
+		}
+	}
+	result->patterns_total++;
+
+	/* allocate storage for patterns */
+	result->patterns = (Name *) getmem(sizeof(Name) * result->patterns_total);
+
+	/* then create patterns */
+	cp = wcb.get_string();
+	pattern = 0;
+	while (true) {
+		cp1 = (wchar_t *) wschr(cp, (int) percent_char);
+		if (cp1 != NULL) {
+			result->patterns[pattern] = GETNAME(cp, cp1 - cp);
+			cp = cp1 + 1;
+			pattern++;
+		} else {
+			result->patterns[pattern] = GETNAME(cp, (int) target->hash.length - (cp - wcb.get_string()));
+			break;
+		}
+	}
+
+	Wstring wcb1;
+
+	/* build dependencies list */
+	for (nvp = depes; nvp != NULL; nvp = nvp->next) {
+		for (i = 0; i < nvp->used; i++) {
+			depe = ALLOC(Percent);
+			depe->next = NULL;
+			depe->patterns = NULL;
+			depe->patterns_total = 0;
+			depe->name = nvp->names[i];
+			depe->dependencies = NULL;
+			depe->command_template = NULL;
+			depe->being_expanded = false;
+			depe->target_group = NULL;
+
+			*depe_tail = depe;
+			depe_tail = &depe->next;
+
+			if (depe->name->percent) {
+				/* get patterns count */
+				wcb1.init(depe->name);
+				cp = wcb1.get_string();
+				while (true) {
+					cp = (wchar_t *) wschr(cp, (int) percent_char);
+					if (cp != NULL) {
+						depe->patterns_total++;
+						cp++;
+					} else {
+						break;
+					}
+				}
+				depe->patterns_total++;
+
+				/* allocate storage for patterns */
+				depe->patterns = (Name *) getmem(sizeof(Name) * depe->patterns_total);
+
+				/* then create patterns */
+				cp = wcb1.get_string();
+				pattern = 0;
+				while (true) {
+					cp1 = (wchar_t *) wschr(cp, (int) percent_char);
+					if (cp1 != NULL) {
+						depe->patterns[pattern] = GETNAME(cp, cp1 - cp);
+						cp = cp1 + 1;
+						pattern++;
+					} else {
+						depe->patterns[pattern] = GETNAME(cp, (int) depe->name->hash.length - (cp - wcb1.get_string()));
+						break;
+					}
+				}
+			}
+		}
+	}
+
+	/* Find the end of the percent list and append the new pattern */
+	for (insert = &percent_list; (*insert) != NULL; insert = &(*insert)->next);
+	*insert = result;
+
+	if (trace_reader) {
+		(void) printf("%s:", result->name->string_mb);
+
+		for (depe = result->dependencies; depe != NULL; depe = depe->next) {
+			(void) printf(" %s", depe->name->string_mb);
+		}
+
+		(void) printf("\n");
+
+		print_rule(command);
+	}
+
+	return result;
+}
+
+/*
+ *	enter_dyntarget(target)
+ *
+ *	Enter "$$(MACRO) : b" type lines
+ *
+ *	Parameters:
+ *		target		Left hand side of pattern
+ *
+ *	Global variables used:
+ *		dyntarget_list	The list of all percent rules, added to
+ *		trace_reader	Indicates that we should echo stuff we read
+ */
+Dyntarget
+enter_dyntarget(register Name target)
+{
+	register Dyntarget	result = ALLOC(Dyntarget);
+	Dyntarget		p;
+	Dyntarget		*insert;
+	int				i;
+
+	result->next = NULL;
+	result->name = target;
+
+
+	/* Find the end of the dyntarget list and append the new pattern */
+	for (insert = &dyntarget_list, p = *insert;
+	     p != NULL;
+	     insert = &p->next, p = *insert);
+	*insert = result;
+
+	if (trace_reader) {
+		(void) printf(NOCATGETS("Dynamic target %s:\n"), result->name->string_mb);
+	}
+	return( result);
+}
+
+
+/*
+ *	special_reader(target, depes, command)
+ *
+ *	Read the pseudo targets make knows about
+ *	This handles the special targets that should not be entered as regular
+ *	target/dependency sets.
+ *
+ *	Parameters:
+ *		target		The special target
+ *		depes		The list of dependencies it was entered with
+ *		command		The command it was entered with
+ *
+ *	Static variables used:
+ *		built_last_make_run_seen Set to indicate .BUILT_LAST... seen
+ *
+ *	Global variables used:
+ *		all_parallel	Set to indicate that everything runs parallel
+ *		svr4 		Set when ".SVR4" target is read
+ *		svr4_name	The Name ".SVR4"
+ *		posix 		Set when ".POSIX" target is read
+ *		posix_name	The Name ".POSIX"
+ *		current_make_version The Name "<current version number>"
+ *		default_rule	Set when ".DEFAULT" target is read
+ *		default_rule_name The Name ".DEFAULT", used for tracing
+ *		dot_keep_state	The Name ".KEEP_STATE", used for tracing
+ *		ignore_errors	Set if ".IGNORE" target is read
+ *		ignore_name	The Name ".IGNORE", used for tracing
+ *		keep_state	Set if ".KEEP_STATE" target is read
+ *		no_parallel_name The Name ".NO_PARALLEL", used for tracing
+ *		only_parallel	Set to indicate only some targets runs parallel
+ *		parallel_name	The Name ".PARALLEL", used for tracing
+ *		precious	The Name ".PRECIOUS", used for tracing
+ *		sccs_get_name	The Name ".SCCS_GET", used for tracing
+ *		sccs_get_posix_name The Name ".SCCS_GET_POSIX", used for tracing
+ *		get_name	The Name ".GET", used for tracing
+ *		sccs_get_rule	Set when ".SCCS_GET" target is read
+ *		silent		Set when ".SILENT" target is read
+ *		silent_name	The Name ".SILENT", used for tracing
+ *		trace_reader	Indicates that we should echo stuff we read
+ */
+void
+special_reader(Name target, register Name_vector depes, Cmd_line command)
+{
+	register int		n;
+
+	switch (target->special_reader) {
+
+	case svr4_special:
+		if (depes->used != 0) {
+			fatal_reader(catgets(catd, 1, 98, "Illegal dependencies for target `%s'"),
+				     target->string_mb);
+		}
+		svr4  = true;
+		posix  = false;
+		keep_state = false;
+		all_parallel = false;
+		only_parallel = false;
+		if (trace_reader) {
+			(void) printf("%s:\n", svr4_name->string_mb);
+		}
+		break;
+
+	case posix_special:
+		if(svr4)
+		  break;
+		if (depes->used != 0) {
+			fatal_reader(catgets(catd, 1, 99, "Illegal dependencies for target `%s'"),
+				     target->string_mb);
+		}
+		posix  = true;
+			/* with posix on, use the posix get rule */
+		sccs_get_rule = sccs_get_posix_rule;
+			/* turn keep state off being SunPro make specific */
+		keep_state = false;
+		#if defined(SUN5_0)
+		/* Use /usr/xpg4/bin/sh on Solaris */
+		MBSTOWCS(wcs_buffer, NOCATGETS("/usr/xpg4/bin/sh"));
+		(void) SETVAR(shell_name, GETNAME(wcs_buffer, FIND_LENGTH), false);
+		#endif
+		if (trace_reader) {
+			(void) printf("%s:\n", posix_name->string_mb);
+		}
+		break;
+
+	case built_last_make_run_special:
+		built_last_make_run_seen = true;
+		break;
+
+	case default_special:
+		if (depes->used != 0) {
+			warning(catgets(catd, 1, 100, "Illegal dependency list for target `%s'"),
+				target->string_mb);
+		}
+		default_rule = command;
+		if (trace_reader) {
+			(void) printf("%s:\n",
+				      default_rule_name->string_mb);
+			print_rule(command);
+		}
+		break;
+
+#ifdef NSE
+	case derived_src_special:
+		for (; depes != NULL; depes= depes->next)
+			for (n= 0; n < depes->used; n++) {
+				if (trace_reader)
+					(void)printf("%s:\t%s\n",
+					precious->string_mb,
+					depes->names[n]->string_mb);
+				depes->names[n]->stat.is_derived_src= true;
+			};
+	        break;
+#endif
+
+	case ignore_special:
+		if ((depes->used != 0) &&(!posix)){
+			fatal_reader(catgets(catd, 1, 101, "Illegal dependencies for target `%s'"),
+				     target->string_mb);
+		}
+		if (depes->used == 0)
+		{
+		   ignore_errors_all = true;
+		}
+		if(svr4) {
+		  ignore_errors_all = true;
+		  break;
+		}
+		for (; depes != NULL; depes = depes->next) {
+			for (n = 0; n < depes->used; n++) {
+				depes->names[n]->ignore_error_mode = true;
+			}
+		}
+		if (trace_reader) {
+			(void) printf("%s:\n", ignore_name->string_mb);
+		}
+		break;
+
+	case keep_state_special:
+		if(svr4)
+		  break;
+			/* ignore keep state, being SunPro make specific */
+		if(posix)
+		  break;
+		if (depes->used != 0) {
+			fatal_reader(catgets(catd, 1, 102, "Illegal dependencies for target `%s'"),
+				     target->string_mb);
+		}
+		keep_state = true;
+		if (trace_reader) {
+			(void) printf("%s:\n",
+				      dot_keep_state->string_mb);
+		}
+		break;
+
+	case keep_state_file_special:
+		if(svr4)
+		  break;
+		if(posix)
+		  break;
+			/* it's not necessary to specify KEEP_STATE, if this 
+			** is given, so set the keep_state.
+			*/
+		keep_state = true;
+		if (depes->used != 0) {
+		   if((!make_state) ||(!strcmp(make_state->string_mb,NOCATGETS(".make.state")))) {
+		     make_state = depes->names[0];
+		   }
+		}
+		break;
+	case make_version_special:
+		if(svr4)
+		  break;
+		if (depes->used != 1) {
+			fatal_reader(catgets(catd, 1, 103, "Illegal dependency list for target `%s'"),
+				     target->string_mb);
+		}
+		if (depes->names[0] != current_make_version) {
+			/*
+			 * Special case the fact that version 1.0 and 1.1
+			 * are identical.
+			 */
+			if (!IS_EQUAL(depes->names[0]->string_mb,
+				      NOCATGETS("VERSION-1.1")) ||
+			    !IS_EQUAL(current_make_version->string_mb,
+				      NOCATGETS("VERSION-1.0"))) {
+				/*
+				 * Version mismatches should cause the
+				 * .make.state file to be skipped.
+				 * This is currently not true - it is read
+				 * anyway.
+				 */
+				warning(catgets(catd, 1, 104, "Version mismatch between current version `%s' and `%s'"),
+					current_make_version->string_mb,
+					depes->names[0]->string_mb);
+			}
+		}
+		break;
+
+	case no_parallel_special:
+		if(svr4)
+		  break;
+		/* Set the no_parallel bit for all the targets on */
+		/* the dependency list */
+		if (depes->used == 0) {
+			/* only those explicitly made parallel */
+			only_parallel = true;
+			all_parallel = false;
+		}
+		for (; depes != NULL; depes = depes->next) {
+			for (n = 0; n < depes->used; n++) {
+				if (trace_reader) {
+					(void) printf("%s:\t%s\n",
+						      no_parallel_name->string_mb,
+						      depes->names[n]->string_mb);
+				}
+				depes->names[n]->no_parallel = true;
+				depes->names[n]->parallel = false;
+			}
+		}
+		break;
+
+	case parallel_special:
+		if(svr4)
+		  break;
+		if (depes->used == 0) {
+			/* everything runs in parallel */
+			all_parallel = true;
+			only_parallel = false;
+		}
+		/* Set the parallel bit for all the targets on */
+		/* the dependency list */
+		for (; depes != NULL; depes = depes->next) {
+			for (n = 0; n < depes->used; n++) {
+				if (trace_reader) {
+					(void) printf("%s:\t%s\n",
+						      parallel_name->string_mb,
+						      depes->names[n]->string_mb);
+				}
+				depes->names[n]->parallel = true;
+				depes->names[n]->no_parallel = false;
+			}
+		}
+		break;
+
+	case localhost_special:
+		if(svr4)
+		  break;
+		/* Set the no_parallel bit for all the targets on */
+		/* the dependency list */
+		if (depes->used == 0) {
+			/* only those explicitly made parallel */
+			only_parallel = true;
+			all_parallel = false;
+		}
+		for (; depes != NULL; depes = depes->next) {
+			for (n = 0; n < depes->used; n++) {
+				if (trace_reader) {
+					(void) printf("%s:\t%s\n",
+						      localhost_name->string_mb,
+						      depes->names[n]->string_mb);
+				}
+				depes->names[n]->no_parallel = true;
+				depes->names[n]->parallel = false;
+				depes->names[n]->localhost = true;
+			}
+		}
+		break;
+
+	case precious_special:
+		if (depes->used == 0) {
+			/* everything is precious      */
+			all_precious = true;
+		} else {
+			all_precious = false;
+		}
+		if(svr4) {
+		  all_precious = true;
+		  break;
+		}
+		/* Set the precious bit for all the targets on */
+		/* the dependency list */
+		for (; depes != NULL; depes = depes->next) {
+			for (n = 0; n < depes->used; n++) {
+				if (trace_reader) {
+					(void) printf("%s:\t%s\n",
+						      precious->string_mb,
+						      depes->names[n]->string_mb);
+				}
+				depes->names[n]->stat.is_precious = true;
+			}
+		}
+		break;
+
+	case sccs_get_special:
+		if (depes->used != 0) {
+			fatal_reader(catgets(catd, 1, 105, "Illegal dependencies for target `%s'"),
+				     target->string_mb);
+		}
+		sccs_get_rule = command;
+		sccs_get_org_rule = command;
+		if (trace_reader) {
+			(void) printf("%s:\n", sccs_get_name->string_mb);
+			print_rule(command);
+		}
+		break;
+
+	case sccs_get_posix_special:
+		if (depes->used != 0) {
+			fatal_reader(catgets(catd, 1, 106, "Illegal dependencies for target `%s'"),
+				     target->string_mb);
+		}
+		sccs_get_posix_rule = command;
+		if (trace_reader) {
+			(void) printf("%s:\n", sccs_get_posix_name->string_mb);
+			print_rule(command);
+		}
+		break;
+
+	case get_posix_special:
+		if (depes->used != 0) {
+			fatal_reader(catgets(catd, 1, 107, "Illegal dependencies for target `%s'"),
+				     target->string_mb);
+		}
+		get_posix_rule = command;
+		if (trace_reader) {
+			(void) printf("%s:\n", get_posix_name->string_mb);
+			print_rule(command);
+		}
+		break;
+
+	case get_special:
+		if(!svr4) {
+		  break;
+		}
+		if (depes->used != 0) {
+			fatal_reader(catgets(catd, 1, 108, "Illegal dependencies for target `%s'"),
+				     target->string_mb);
+		}
+		get_rule = command;
+		sccs_get_rule = command;
+		if (trace_reader) {
+			(void) printf("%s:\n", get_name->string_mb);
+			print_rule(command);
+		}
+		break;
+
+	case silent_special:
+		if ((depes->used != 0) && (!posix)){
+			fatal_reader(catgets(catd, 1, 109, "Illegal dependencies for target `%s'"),
+				     target->string_mb);
+		}
+		if (depes->used == 0)
+		{
+		   silent_all = true;
+		}
+		if(svr4) {
+		  silent_all = true;
+		  break;
+		}
+		for (; depes != NULL; depes = depes->next) {
+			for (n = 0; n < depes->used; n++) {
+				depes->names[n]->silent_mode = true;
+			}
+		}
+		if (trace_reader) {
+			(void) printf("%s:\n", silent_name->string_mb);
+		}
+		break;
+
+	case suffixes_special:
+		read_suffixes_list(depes);
+		break;
+
+	default:
+
+		fatal_reader(catgets(catd, 1, 110, "Internal error: Unknown special reader"));
+	}
+}
+
+/*
+ *	read_suffixes_list(depes)
+ *
+ *	Read the special list .SUFFIXES. If it is empty the old list is
+ *	cleared. Else the new one is appended. Suffixes with ~ are extracted
+ *	and marked.
+ *
+ *	Parameters:
+ *		depes		The list of suffixes
+ *
+ *	Global variables used:
+ *		hashtab		The central hashtable for Names.
+ *		suffixes	The list of suffixes, set or appended to
+ *		suffixes_name	The Name ".SUFFIXES", used for tracing
+ *		trace_reader	Indicates that we should echo stuff we read
+ */
+static void
+read_suffixes_list(register Name_vector depes)
+{
+	register int		n;
+	register Dependency	dp;
+	register Dependency	*insert_dep;
+	register Name		np;
+	Name			np2;
+	register Boolean	first = true;
+
+	if (depes->used == 0) {
+		/* .SUFFIXES with no dependency list clears the */
+		/* suffixes list */
+		for (Name_set::iterator np = hashtab.begin(), e = hashtab.end(); np != e; np++) {
+				np->with_squiggle =
+				  np->without_squiggle =
+				    false;
+		}
+		suffixes = NULL;
+		if (trace_reader) {
+			(void) printf("%s:\n", suffixes_name->string_mb);
+		}
+		return;
+	}
+	Wstring str;
+	/* Otherwise we append to the list */
+	for (; depes != NULL; depes = depes->next) {
+		for (n = 0; n < depes->used; n++) {
+			np = depes->names[n];
+			/* Find the end of the list and check if the */
+			/* suffix already has been entered */
+			for (insert_dep = &suffixes, dp = *insert_dep;
+			     dp != NULL;
+			     insert_dep = &dp->next, dp = *insert_dep) {
+				if (dp->name == np) {
+					goto duplicate_suffix;
+				}
+			}
+			if (trace_reader) {
+				if (first) {
+					(void) printf("%s:\t",
+						      suffixes_name->string_mb);
+					first = false;
+				}
+				(void) printf("%s ", depes->names[n]->string_mb);
+			}
+		if(!(posix|svr4)) {
+			/* If the suffix is suffixed with "~" we */
+			/* strip that and mark the suffix nameblock */
+			str.init(np);
+			wchar_t * wcb = str.get_string();
+			if (wcb[np->hash.length - 1] ==
+			    (int) tilde_char) {
+				np2 = GETNAME(wcb,
+					      (int)(np->hash.length - 1));
+				np2->with_squiggle = true;
+				if (np2->without_squiggle) {
+					continue;
+				}
+				np = np2;
+			}
+		}
+			np->without_squiggle = true;
+			/* Add the suffix to the list */
+			dp = *insert_dep = ALLOC(Dependency);
+			insert_dep = &dp->next;
+			dp->next = NULL;
+			dp->name = np;
+			dp->built = false;
+		duplicate_suffix:;
+		}
+	}
+	if (trace_reader) {
+		(void) printf("\n");
+	}
+}
+
+/*
+ *	make_relative(to, result)
+ *
+ *	Given a file name compose a relative path name from it to the
+ *	current directory.
+ *
+ *	Parameters:
+ *		to		The path we want to make relative
+ *		result		Where to put the resulting relative path
+ *
+ *	Global variables used:
+ */
+static void
+make_relative(wchar_t *to, wchar_t *result)
+{
+	wchar_t			*from;
+	wchar_t			*allocated;
+	wchar_t			*cp;
+	wchar_t			*tocomp;
+	int			ncomps;
+	int			i;
+	int			len;
+
+	/* Check if the path is already relative. */
+	if (to[0] != (int) slash_char) {
+		(void) wscpy(result, to);
+		return;
+	}
+
+	MBSTOWCS(wcs_buffer, get_current_path());
+	from = allocated = (wchar_t *) wsdup(wcs_buffer);
+
+	/*
+	 * Find the number of components in the from name.
+	 * ncomp = number of slashes + 1.
+	 */
+	ncomps = 1;
+	for (cp = from; *cp != (int) nul_char; cp++) {
+		if (*cp == (int) slash_char) {
+			ncomps++;
+		}
+	}
+
+	/*
+	 * See how many components match to determine how many "..",
+	 * if any, will be needed.
+	 */
+	result[0] = (int) nul_char;
+	tocomp = to;
+	while ((*from != (int) nul_char) && (*from == *to)) {
+		if (*from == (int) slash_char) {
+			ncomps--;
+			tocomp = &to[1];
+		}
+		from++;
+		to++;
+	}
+
+	/*
+	 * Now for some special cases. Check for exact matches and
+	 * for either name terminating exactly.
+	 */
+	if (*from == (int) nul_char) {
+		if (*to == (int) nul_char) {
+			MBSTOWCS(wcs_buffer, ".");
+			(void) wscpy(result, wcs_buffer);
+			retmem(allocated);
+			return;
+		}
+		if (*to == (int) slash_char) {
+			ncomps--;
+			tocomp = &to[1];
+		}
+	} else if ((*from == (int) slash_char) && (*to == (int) nul_char)) {
+		ncomps--;
+		tocomp = to;
+	}
+	/* Add on the ".."s. */
+	for (i = 0; i < ncomps; i++) {
+		MBSTOWCS(wcs_buffer, "../");
+		(void) wscat(result, wcs_buffer);
+	}
+
+	/* Add on the remainder of the to name, if any. */
+	if (*tocomp == (int) nul_char) {
+		len = wslen(result);
+		result[len - 1] = (int) nul_char;
+	} else {
+		(void) wscat(result, tocomp);
+	}
+	retmem(allocated);
+	return;
+}
+
+/*
+ *	print_rule(command)
+ *
+ *	Used when tracing the reading of rules
+ *
+ *	Parameters:
+ *		command		Command to print
+ *
+ *	Global variables used:
+ */
+static void
+print_rule(register Cmd_line command)
+{
+	for (; command != NULL; command = command->next) {
+		(void) printf("\t%s\n", command->command_line->string_mb);
+	}
+}
+
+/*
+ *	enter_conditional(target, name, value, append)
+ *
+ *	Enter "target := MACRO= value" constructs
+ *
+ *	Parameters:
+ *		target		The target the macro is for
+ *		name		The name of the macro
+ *		value		The value for the macro
+ *		append		Indicates if the assignment is appending or not
+ *
+ *	Global variables used:
+ *		conditionals	A special Name that stores all conditionals
+ *				where the target is a % pattern
+ *		trace_reader	Indicates that we should echo stuff we read
+ */
+void
+enter_conditional(register Name target, Name name, Name value, register Boolean append)
+{
+	register Property	conditional;
+	static int		sequence;
+	Name			orig_target = target;
+
+	if (name == target_arch) {
+		enter_conditional(target, virtual_root, virtual_root, false);
+	}
+
+	if (target->percent) {
+		target = conditionals;
+	}
+	
+	if (name->colon) {
+		sh_transform(&name, &value);
+	}
+
+	/* Count how many conditionals we must activate before building the */
+	/* target */
+	if (target->percent) {
+		target = conditionals;
+	}
+
+	target->conditional_cnt++;
+	maybe_append_prop(name, macro_prop)->body.macro.is_conditional = true;
+	/* Add the property for the target */
+	conditional = append_prop(target, conditional_prop);
+	conditional->body.conditional.target = orig_target;
+	conditional->body.conditional.name = name;
+	conditional->body.conditional.value = value;
+	conditional->body.conditional.sequence = sequence++;
+	conditional->body.conditional.append = append;
+	if (trace_reader) {
+		if (value == NULL) {
+			(void) printf("%s := %s %c=\n",
+				      target->string_mb,
+				      name->string_mb,
+				      append ?
+				      (int) plus_char : (int) space_char);
+		} else {
+			(void) printf("%s := %s %c= %s\n",
+				      target->string_mb,
+				      name->string_mb,
+				      append ?
+				      (int) plus_char : (int) space_char,
+				      value->string_mb);
+		}
+	}
+}
+
+/*
+ *	enter_equal(name, value, append)
+ *
+ *	Enter "MACRO= value" constructs
+ *
+ *	Parameters:
+ *		name		The name of the macro
+ *		value		The value for the macro
+ *		append		Indicates if the assignment is appending or not
+ *
+ *	Global variables used:
+ *		trace_reader	Indicates that we should echo stuff we read
+ */
+void
+enter_equal(Name name, Name value, register Boolean append)
+{
+	wchar_t		*string;
+	Name		temp;
+
+	if (name->colon) {
+		sh_transform(&name, &value);
+	}
+	(void) SETVAR(name, value, append);
+
+	/* if we're setting FC, we want to set F77 to the same value. */
+	Wstring nms(name);
+	wchar_t * wcb = nms.get_string();
+	string = wcb;
+	if (string[0]=='F' &&
+	    string[1]=='C' &&
+	    string[2]=='\0') {
+		MBSTOWCS(wcs_buffer, NOCATGETS("F77"));
+		temp = GETNAME(wcs_buffer, FIND_LENGTH);
+		(void) SETVAR(temp, value, append);
+/*
+		fprintf(stderr, catgets(catd, 1, 111, "warning: FC is obsolete, use F77 instead\n"));
+ */
+	}
+
+	if (trace_reader) {
+		if (value == NULL) {
+			(void) printf("%s %c=\n",
+				      name->string_mb,
+				      append ?
+				      (int) plus_char : (int) space_char);
+		} else {
+			(void) printf("%s %c= %s\n",
+				      name->string_mb,
+				      append ?
+				      (int) plus_char : (int) space_char,
+				      value->string_mb);
+		}
+	}
+}
+
+/*
+ *	sh_transform(name, value)
+ *
+ *	Parameters:
+ *		name	The name of the macro we might transform
+ *		value	The value to transform
+ *
+ */
+static void
+sh_transform(Name *name, Name *value)
+{
+	/* Check if we need :sh transform */
+	wchar_t		*colon;
+	String_rec	command;
+	String_rec	destination;
+	wchar_t		buffer[1000];
+	wchar_t		buffer1[1000];
+
+	static wchar_t	colon_sh[4];
+	static wchar_t	colon_shell[7];
+
+	if (colon_sh[0] == (int) nul_char) {
+		MBSTOWCS(colon_sh, NOCATGETS(":sh"));
+		MBSTOWCS(colon_shell, NOCATGETS(":shell"));
+	}
+	Wstring nms((*name));
+	wchar_t * wcb = nms.get_string();
+
+	colon = (wchar_t *) wsrchr(wcb, (int) colon_char);
+	if ((colon != NULL) && (IS_WEQUAL(colon, colon_sh) || IS_WEQUAL(colon, colon_shell))) {
+		INIT_STRING_FROM_STACK(destination, buffer);
+
+		if(*value == NULL) {
+			buffer[0] = 0;
+		} else {
+			Wstring wcb1((*value));
+			if (IS_WEQUAL(colon, colon_shell)) {
+				INIT_STRING_FROM_STACK(command, buffer1);
+				expand_value(*value, &command, false);
+			} else {
+				command.text.p = wcb1.get_string() + (*value)->hash.length;
+				command.text.end = command.text.p;
+				command.buffer.start = wcb1.get_string();
+				command.buffer.end = command.text.p;
+			}
+			sh_command2string(&command, &destination);
+		}
+
+		(*value) = GETNAME(destination.buffer.start, FIND_LENGTH);
+		*colon = (int) nul_char;
+		(*name) = GETNAME(wcb, FIND_LENGTH);
+		*colon = (int) colon_char;
+	}
+}
+
+/*
+ *	fatal_reader(format, args...)
+ *
+ *	Parameters:
+ *		format		printf style format string
+ *		args		arguments to match the format
+ *
+ *	Global variables used:
+ *		file_being_read	Name of the makefile being read
+ *		line_number	Line that is being read
+ *		report_pwd	Indicates whether current path should be shown
+ *		temp_file_name	When reading tempfile we report that name
+ */
+/*VARARGS*/
+void
+fatal_reader(char * pattern, ...)
+{
+	va_list args;
+	char	message[1000];
+
+	va_start(args, pattern);
+	if (file_being_read != NULL) {
+		WCSTOMBS(mbs_buffer, file_being_read);
+		if (line_number != 0) {
+			(void) sprintf(message,
+				       catgets(catd, 1, 112, "%s, line %d: %s"),
+				       mbs_buffer,
+				       line_number,
+				       pattern);
+		} else {
+			(void) sprintf(message,
+				       "%s: %s",
+				       mbs_buffer,
+				       pattern);
+		}
+		pattern = message;
+	}
+
+	(void) fflush(stdout);
+#ifdef DISTRIBUTED
+	(void) fprintf(stderr, catgets(catd, 1, 113, "dmake: Fatal error in reader: "));
+#else
+	(void) fprintf(stderr, catgets(catd, 1, 238, "make: Fatal error in reader: "));
+#endif
+	(void) vfprintf(stderr, pattern, args);
+	(void) fprintf(stderr, "\n");
+	va_end(args);
+
+	if (temp_file_name != NULL) {
+		(void) fprintf(stderr,
+#ifdef DISTRIBUTED
+			       catgets(catd, 1, 114, "dmake: Temp-file %s not removed\n"),
+#else
+			       catgets(catd, 1, 239, "make: Temp-file %s not removed\n"),
+#endif
+			       temp_file_name->string_mb);
+		temp_file_name = NULL;
+	}
+
+	if (report_pwd) {
+		(void) fprintf(stderr,
+			       catgets(catd, 1, 115, "Current working directory %s\n"),
+			       get_current_path());
+	}
+	(void) fflush(stderr);
+#if defined(SUN5_0) || defined(HP_UX)
+	exit_status = 1;
+#endif
+	exit(1);
+}
+
--- /dev/null	2015-05-20 11:04:11.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/common/rep.cc	2015-05-20 11:04:11.294538992 -0400
@@ -0,0 +1,529 @@
+/*
+ * 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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)rep.cc 1.25 06/12/12
+ */
+
+#pragma	ident	"@(#)rep.cc	1.25	06/12/12"
+
+/*
+ *	rep.c
+ *
+ *	This file handles the .nse_depinfo file
+ */
+
+/*
+ * Included files
+ */ 
+#include <mk/defs.h>
+#include <mksh/misc.h>		/* retmem() */
+#include <vroot/report.h>	/* NSE_DEPINFO */
+
+/*
+ * Static variables
+ */
+static	Recursive_make	recursive_list;
+static	Recursive_make	*bpatch = &recursive_list;
+static	Boolean		changed;
+
+/*
+ * File table of contents
+ */
+
+
+/*
+ *	report_recursive_init()
+ *
+ *	Read the .nse_depinfo file and make a list of all the
+ *	.RECURSIVE entries.
+ *
+ *	Parameters:
+ *
+ *	Static variables used:
+ *		bpatch		Points to slot where next cell should be added
+ *
+ *	Global variables used:
+ *		recursive_name	The Name ".RECURSIVE", compared against
+ */
+
+void
+report_recursive_init(void)
+{
+	char		*search_dir;
+	char		nse_depinfo[MAXPATHLEN];
+	FILE		*fp;
+	int		line_size, line_index;
+	wchar_t		*line;
+	wchar_t		*bigger_line;
+	wchar_t		*colon;
+	wchar_t		*dollar; 
+	Recursive_make	rp;
+
+	/*
+	 * This routine can be called more than once,  don't do
+	 * anything after the first time.
+	 */
+	if (depinfo_already_read) {
+		return;
+	} else {
+		depinfo_already_read = true;
+	}
+					
+	search_dir = getenv(NOCATGETS("NSE_DEP"));
+	if (search_dir == NULL) {
+		return;
+	}
+	(void) sprintf(nse_depinfo, "%s/%s", search_dir, NSE_DEPINFO);
+	fp = fopen(nse_depinfo, "r");
+	if (fp == NULL) {
+		return;
+	}
+	line_size = MAXPATHLEN;
+	line_index = line_size - 1;
+	line = ALLOC_WC(line_size);
+	Wstring rns(recursive_name);
+	wchar_t * wcb = rns.get_string();
+	while (fgetws(line, line_size, fp) != NULL) {
+		while (wslen(line) == line_index) {
+			if (line[wslen(line) - 1] == '\n') {
+				continue;
+			}
+			bigger_line = ALLOC_WC(2 * line_size);
+			wscpy(bigger_line, line);
+			retmem(line);
+			line = bigger_line;
+			if (fgetws(&line[line_index], line_size, fp) == NULL)
+				continue;
+			line_index = 2 * line_index;
+			line_size = 2 * line_size;
+		}
+
+		colon = (wchar_t *) wschr(line, (int) colon_char);
+		if (colon == NULL) {
+			continue;
+		}
+		dollar = (wchar_t *) wschr(line, (int) dollar_char);
+		line[wslen(line) - 1] = (int) nul_char;
+		if (IS_WEQUALN(&colon[2], wcb,
+	            (int) recursive_name->hash.length)) {
+			/*
+			 * If this entry is an old entry, ignore it
+			 */
+			MBSTOWCS(wcs_buffer, DEPINFO_FMT_VERSION);
+			if (dollar == NULL ||
+			    !IS_WEQUALN(wcs_buffer, (dollar+1) - VER_LEN, VER_LEN)){
+				continue;
+			    }
+			rp = ALLOC(Recursive_make);
+			(void) memset((char *) rp, 0, sizeof (Recursive_make_rec));
+			/*
+			 * set conditional_macro_string if string is present
+			 */
+			rp->oldline = (wchar_t *) wsdup(line);
+			if ( dollar != NULL ){
+				rp->cond_macrostring = 
+				    (wchar_t *) wsdup(dollar - VER_LEN + 1);
+			}
+			/* 
+			 * get target name into recursive struct
+			 */
+			*colon = (int) nul_char;
+			rp->target = (wchar_t *) wsdup(line);
+			*bpatch = rp;
+			bpatch = &rp->next;
+		}
+	}
+	(void) fclose(fp);
+}
+
+/*
+ *	report_recursive_dep(target, line)
+ *
+ *	Report a target as recursive.
+ *
+ *	Parameters:
+ *		line		Dependency line reported
+ *
+ *	Static variables used:
+ *		bpatch		Points to slot where next cell should be added
+ *		changed		Written if report set changed
+ */
+void
+report_recursive_dep(Name target, wchar_t *line)
+{
+	Recursive_make	rp;
+	wchar_t		rec_buf[STRING_BUFFER_LENGTH];
+	String_rec	string;
+
+	INIT_STRING_FROM_STACK(string, rec_buf);
+	cond_macros_into_string(target, &string);
+	/* 
+	 * find an applicable recursive entry, if there isn't one, create it
+	 */
+	rp = find_recursive_target(target);
+	if (rp == NULL) {
+		rp = ALLOC(Recursive_make);
+		(void) memset((char *) rp, 0, sizeof (Recursive_make_rec));
+		wchar_t * wcb = get_wstring(target->string_mb); // XXX Tolik: needs retmem
+                rp->target = wcb;
+		rp->newline = (wchar_t *) wsdup(line);
+		rp->cond_macrostring = (wchar_t *) wsdup(rec_buf);
+		*bpatch = rp;
+		bpatch = &rp->next;
+		changed = true;
+	} else {
+		if ((rp->oldline != NULL) && !IS_WEQUAL(rp->oldline, line)) {
+			rp->newline = (wchar_t *) wsdup(line);
+			changed = true;
+		}
+		rp->removed = false;
+	}
+}
+
+/*
+ *	find_recursive_target(target)
+ *
+ *	Search the list for a given target.
+ *
+ *	Return value:
+ *				The target cell
+ *
+ *	Parameters:
+ *		target		The target we need
+ *		top_level_target more info used to determinde the 
+ *				 target we need
+ *
+ *	Static variables used:
+ *		recursive_list	The list of targets
+ */
+Recursive_make
+find_recursive_target(Name target)
+{
+	Recursive_make	rp;
+	String_rec	string;
+	wchar_t		rec_buf[STRING_BUFFER_LENGTH]; 
+
+	INIT_STRING_FROM_STACK(string, rec_buf);
+	cond_macros_into_string(target, &string);
+
+	Wstring tstr(target);
+	wchar_t * wcb = tstr.get_string();
+	for (rp = recursive_list; rp != NULL; rp = rp->next) {
+		/* 
+		 * If this entry has already been removed, ignore it.
+		 */
+		if (rp->removed)
+			continue;
+		/* 
+		 * If this target, and the target on the list are the same
+		 * and if one of them contains conditional macro info, while
+		 * the other doesn't,  remove this entry from the list of
+		 * recursive entries.  This can only happen if the Makefile
+		 * has changed to no longer contain conditional macros.
+		 */
+		if (IS_WEQUAL(rp->target, wcb)) {
+			if (rp->cond_macrostring[VER_LEN] == '\0' &&
+			    string.buffer.start[VER_LEN] != '\0'){
+				rp->removed = true;
+				continue;
+			} else if (rp->cond_macrostring[VER_LEN] != '\0' &&
+			    string.buffer.start[VER_LEN] == '\0'){
+				rp->removed = true;
+				continue;
+			} 
+		}
+		/*
+		 * If this is not a VERS2 entry,  only need to match
+		 * the target name.  toptarg information from VERS1 entries
+		 * are ignored.
+		 */
+		MBSTOWCS(wcs_buffer, DEPINFO_FMT_VERSION);
+		if (IS_WEQUALN(wcs_buffer, string.buffer.start, VER_LEN)) { 
+			if (IS_WEQUAL(rp->cond_macrostring, 
+			    string.buffer.start) &&
+			    IS_WEQUAL(rp->target, wcb)) {
+				return rp;
+			}
+		} else {
+			if (IS_WEQUAL(rp->target, wcb)) {
+				return rp;
+			}
+		}
+	}
+	return NULL;
+}
+
+/*
+ *	remove_recursive_dep(target, top_level_target)
+ *
+ *	Mark a target as no longer recursive.
+ *
+ *	Parameters:
+ *		target		The target we want to remove
+ *		top_level_target target we want to remove must be built from 
+ *				 the same top level target
+ *
+ *	Static variables used:
+ *		changed		Written if report set changed
+ */
+void
+remove_recursive_dep(Name target)
+{
+	Recursive_make	rp;
+
+	rp = find_recursive_target(target);
+
+	if ( rp != NULL ) {
+		rp->removed = true;	
+		changed = true;
+		if(rp->target) {
+			retmem(rp->target);
+			rp->target = NULL;
+		}
+		if(rp->newline) {
+			retmem(rp->newline);
+			rp->newline = NULL;
+		}
+		if(rp->oldline) {
+			retmem(rp->oldline);
+			rp->oldline = NULL;
+		}
+		if(rp->cond_macrostring) {
+			retmem(rp->cond_macrostring);
+			rp->cond_macrostring = NULL;
+		}
+	}
+}
+
+#ifdef NSE
+/*
+ *	report_recursive_done()
+ *
+ *	Write the .nse_depinfo file.
+ *
+ *	Parameters:
+ *
+ *	Static variables used:
+ *		recursive_list	The list of targets
+ *		changed		Written if report set changed
+ *
+ *	Global variables used:
+ *		recursive_name	The Name ".RECURSIVE", compared against
+ */
+void
+report_recursive_done(void)
+{
+	char		*search_dir;
+	char		nse_depinfo[MAXPATHLEN];
+	char		tmpfile[MAXPATHLEN];
+	FILE		*ofp;
+	FILE		*ifp;
+	wchar_t		*space;
+	wchar_t		*data;
+	wchar_t		*line;
+	wchar_t		*bigger_line;
+	int		line_size, line_index;
+	int		lock_err;
+	Recursive_make	rp;
+
+	if (changed == false) {
+		return;
+	}
+
+	search_dir = getenv(NOCATGETS("NSE_DEP"));
+	if (search_dir == NULL) {
+		return;
+	}
+	(void) sprintf(nse_depinfo, "%s/%s", search_dir, NSE_DEPINFO);
+	(void) sprintf(tmpfile, "%s.%d", nse_depinfo, getpid());
+	ofp = fopen(tmpfile, "w");
+	if (ofp == NULL) {
+		(void) fprintf(stderr,
+			       catgets(catd, 1, 116, "Cannot open `%s' for writing\n"),
+			       tmpfile);
+		return;
+	}
+	(void) sprintf(nse_depinfo_lockfile, 
+		       "%s/%s", search_dir, NSE_DEPINFO_LOCK);
+	if (lock_err = file_lock(nse_depinfo, 
+				 nse_depinfo_lockfile, 
+				 (int *) &nse_depinfo_locked, 0)) {
+		(void) fprintf(stderr,
+			       catgets(catd, 1, 117, "writing .RECURSIVE lines to %s\n"),
+			       tmpfile);
+		(void) fprintf(stderr,
+			       catgets(catd, 1, 118, "To recover, merge .nse_depinfo.%d with .nse_depinfo\n"),
+			       getpid(),
+			       catgets(catd, 1, 119, "with .nse_depinfo"));
+	}
+
+	if (nse_depinfo_locked) {
+		ifp = fopen(nse_depinfo, "r");
+		if (ifp != NULL) {
+			/*
+			 * Copy all the non-.RECURSIVE lines from 
+			 * the old file to the new one.
+			 */
+			line_size = MAXPATHLEN;
+			line_index = line_size - 1;
+			line = ALLOC_WC(line_size);
+			while (fgetws(line, line_size, ifp) != NULL) {
+				while (wslen(line) == line_index) {
+					if (line[wslen(line) - 1] == '\n') {
+						continue;
+					}
+					bigger_line = ALLOC_WC(2 * line_size);
+					wscpy(bigger_line, line);
+					retmem(line);
+					line = bigger_line;
+					if (fgetws(&line[line_index], 
+						  line_size, ifp) == NULL)
+					  continue;
+					line_index = 2 * line_index;
+					line_size = 2 * line_size;
+				}
+
+				space = wschr(line, (int) space_char);
+				if (space != NULL && 
+				    IS_WEQUALN(&space[1],
+					      recursive_name->string,
+					      (int) recursive_name->hash.length)) {
+					continue;
+				}
+				WCSTOMBS(mbs_buffer, line);
+				(void) fprintf(ofp, "%s", mbs_buffer);
+			}
+			(void) fclose(ifp);
+		}
+	}
+
+	/*
+	 * Write out the .RECURSIVE lines.
+	 */
+	for (rp = recursive_list; rp != NULL; rp = rp->next) {
+		if (rp->removed) {
+			continue;
+		}
+		if (rp->newline != NULL) {
+			data = rp->newline;
+		} else {
+			data = rp->oldline;
+		}
+		if (data != NULL) {
+			WCSTOMBS(mbs_buffer, data);
+			(void) fprintf(ofp, "%s\n", mbs_buffer);
+		}
+	}
+	(void) fclose(ofp);
+
+	if (nse_depinfo_locked) {
+		(void) rename(tmpfile, nse_depinfo);
+		(void) unlink(nse_depinfo_lockfile);
+		nse_depinfo_locked = false;
+		nse_depinfo_lockfile[0] = '\0';
+		(void) chmod(nse_depinfo, 0666);
+	}
+}
+#endif // NSE
+
+/* gather_recursive_deps()
+ *
+ *	Create or update list of recursive targets.  
+ */
+void
+gather_recursive_deps(void)
+{
+	Name_set::iterator	np, e;
+	String_rec		rec;
+	wchar_t			rec_buf[STRING_BUFFER_LENGTH];
+	register Property	lines;
+	Boolean			has_recursive;
+	Dependency		dp;
+
+	report_recursive_init();
+
+	/* Go thru all targets and dump recursive dependencies */
+	for (np = hashtab.begin(), e = hashtab.end(); np != e; np++) {
+		if (np->has_recursive_dependency){
+			has_recursive = false;
+			/* 
+			 * start .RECURSIVE line with target:
+			 */
+			INIT_STRING_FROM_STACK(rec, rec_buf);
+			APPEND_NAME(np, &rec, FIND_LENGTH);
+			append_char((int) colon_char, &rec);
+			append_char((int) space_char, &rec);
+			
+			for (lines = get_prop(np->prop,recursive_prop); 
+			    lines != NULL;
+			    lines = get_prop(lines->next, recursive_prop)) {
+				/* 
+				 * if entry is already in depinfo
+				 * file or entry was not built, ignore it
+				 */
+				if (lines->body.recursive.in_depinfo)
+					continue;
+				if (!lines->body.recursive.has_built)
+					continue;
+				has_recursive = true;
+				lines->body.recursive.in_depinfo=true;
+				
+				/* 
+				* Write the remainder of the
+				* .RECURSIVE line 
+				*/
+				APPEND_NAME(recursive_name, &rec, 
+				    FIND_LENGTH);
+				append_char((int) space_char, &rec);
+				APPEND_NAME(lines->body.recursive.directory,
+					&rec, FIND_LENGTH);
+				append_char((int) space_char, &rec);
+				APPEND_NAME(lines->body.recursive.target,
+					&rec, FIND_LENGTH);
+				append_char((int) space_char, &rec);
+				
+				/* Complete list of makefiles used */
+				for (dp = lines->body.recursive.makefiles; 
+				    dp != NULL; 
+				    dp = dp->next) {
+					APPEND_NAME(dp->name, &rec,  FIND_LENGTH);
+					append_char((int) space_char, &rec);
+				}
+			}  
+			/* 
+			 * dump list of conditional targets,
+			 * and report recursive entry, if needed
+			 */
+			cond_macros_into_string(np, &rec);
+			if (has_recursive){
+				report_recursive_dep(np, rec.buffer.start);
+			}
+
+		} else if ( np->has_built ) {
+			remove_recursive_dep(np);
+		}
+	}
+}
+
--- /dev/null	2015-05-20 11:04:11.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/common/state.cc	2015-05-20 11:04:11.492237430 -0400
@@ -0,0 +1,463 @@
+/*
+ * 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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)state.cc 1.27 06/12/12
+ */
+
+#pragma	ident	"@(#)state.cc	1.27	06/12/12"
+
+/*
+ *	state.c
+ *
+ *	This file contains the routines that write the .make.state file
+ */
+
+/*
+ * Included files
+ */
+#include <mk/defs.h>
+#include <mksh/misc.h>		/* errmsg() */
+#include <setjmp.h>		/* setjmp() */
+#include <unistd.h>		/* getpid() */
+#include <errno.h>		/* errno    */
+#include <locale.h>		/* MB_CUR_MAX    */
+
+/*
+ * Defined macros
+ */
+#define LONGJUMP_VALUE 17
+#define XFWRITE(string, length, fd) {if (fwrite(string, 1, length, fd) == 0) \
+					longjmp(long_jump, LONGJUMP_VALUE);}
+#define XPUTC(ch, fd) { \
+	if (putc((int) ch, fd) == EOF) \
+		longjmp(long_jump, LONGJUMP_VALUE); \
+	}
+#define XFPUTS(string, fd) fputs(string, fd)
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+
+/*
+ * File table of contents
+ */
+static char * escape_target_name(Name np)
+{
+	if(np->dollar) {
+		int len = strlen(np->string_mb);
+		char * buff = (char*)malloc(2 * len);
+		int pos = 0;
+		wchar_t wc;
+		int pp = 0;
+		while(pos < len) {
+			int n = mbtowc(&wc, np->string_mb + pos, MB_CUR_MAX);
+			if(n < 0) { // error - this shouldn't happen
+				(void)free(buff);
+				return strdup(np->string_mb);
+			}
+			if(wc == dollar_char) {
+				buff[pp] = '\\'; pp++;
+				buff[pp] = '$'; pp++;
+			} else {
+				for(int j=0;j<n;j++) {
+					buff[pp] = np->string_mb[pos+j]; pp++;
+				}
+			}
+			pos += n;
+		}
+		buff[pp] = '\0';
+		return buff;
+	} else {
+		return strdup(np->string_mb);
+	}
+}
+
+static	void		print_auto_depes(register Dependency dependency, register FILE *fd, register Boolean built_this_run, register int *line_length, register char *target_name, jmp_buf long_jump);
+
+/*
+ *	write_state_file(report_recursive, exiting)
+ *
+ *	Write a new version of .make.state
+ *
+ *	Parameters:
+ *		report_recursive	Should only be done at end of run
+ *		exiting			true if called from the exit handler
+ *
+ *	Global variables used:
+ *		built_last_make_run The Name ".BUILT_LAST_MAKE_RUN", written
+ *		command_changed	If no command changed we do not need to write
+ *		current_make_version The Name "<current version>", written
+ *		do_not_exec_rule If -n is on we do not write statefile
+ *		hashtab		The hashtable that contains all names
+ *		keep_state	If .KEEP_STATE is no on we do not write file
+ *		make_state	The Name ".make.state", used for opening file
+ *		make_version	The Name ".MAKE_VERSION", written
+ *		recursive_name	The Name ".RECURSIVE", written
+ *		rewrite_statefile Indicates that something changed
+ */
+
+void
+#ifdef NSE
+write_state_file(int report_recursive, Boolean exiting)
+#else
+write_state_file(int, Boolean exiting)
+#endif
+{
+	register FILE		*fd;
+	int			lock_err;
+	char			buffer[MAXPATHLEN];
+	char			make_state_tempfile[MAXPATHLEN];
+	jmp_buf			long_jump;
+	register int		attempts = 0;
+	Name_set::iterator	np, e;
+	register Property	lines;
+	register int		m;
+	Dependency		dependency;
+	register Boolean	name_printed;
+	Boolean			built_this_run = false;
+	char			*target_name;
+	int			line_length;
+	register Cmd_line	cp;
+
+
+	if (!rewrite_statefile ||
+	    !command_changed ||
+	    !keep_state ||
+	    do_not_exec_rule ||
+	    (report_dependencies_level > 0)) {
+		return;
+	}
+	/* Lock the file for writing. */
+ 	make_state_lockfile = getmem(strlen(make_state->string_mb) + strlen(NOCATGETS(".lock")) + 1);
+ 	(void) sprintf(make_state_lockfile,
+ 	               NOCATGETS("%s.lock"),
+ 	               make_state->string_mb);
+	if (lock_err = file_lock(make_state->string_mb, 
+				 make_state_lockfile, 
+				 (int *) &make_state_locked, 0)) {
+ 		retmem_mb(make_state_lockfile);
+		make_state_lockfile = NULL;
+		
+		/*
+		 * We need to make sure that we are not being
+		 * called by the exit handler so we don't call
+		 * it again.
+		 */
+		
+		if (exiting) {
+			(void) sprintf(buffer, NOCATGETS("%s/.make.state.%d.XXXXXX"), tmpdir, getpid());
+			report_pwd = true;
+			warning(catgets(catd, 1, 60, "Writing to %s"), buffer);
+			int fdes = mkstemp(buffer);
+			if ((fdes < 0) || (fd = fdopen(fdes, "w")) == NULL) {
+				fprintf(stderr,
+					catgets(catd, 1, 61, "Could not open statefile `%s': %s"),
+					buffer,
+					errmsg(errno));
+				return;
+			}
+		} else {
+			report_pwd = true;
+			fatal(catgets(catd, 1, 62, "Can't lock .make.state"));
+		}
+	}
+
+	(void) sprintf(make_state_tempfile,
+	               NOCATGETS("%s.tmp"),
+	               make_state->string_mb);
+	/* Delete old temporary statefile (in case it exists) */
+	(void) unlink(make_state_tempfile);
+	if ((fd = fopen(make_state_tempfile, "w")) == NULL) {
+		lock_err = errno; /* Save it! unlink() can change errno */
+		(void) unlink(make_state_lockfile);
+ 		retmem_mb(make_state_lockfile);
+		make_state_lockfile = NULL;
+		make_state_locked = false;
+		fatal(catgets(catd, 1, 59, "Could not open temporary statefile `%s': %s"),
+		      make_state_tempfile,
+		      errmsg(lock_err));
+	}
+#ifdef NSE
+	if (nse) {
+		(void) fchmod(fileno(fd), 0666); 
+	}
+#endif
+	/*
+	 * Set a trap for failed writes. If a write fails, the routine
+	 * will try saving the .make.state file under another name in /tmp.
+	 */
+	if (setjmp(long_jump)) {
+		(void) fclose(fd);
+		if (attempts++ > 5) {
+			if ((make_state_lockfile != NULL) &&
+			    make_state_locked) {
+				(void) unlink(make_state_lockfile);
+ 				retmem_mb(make_state_lockfile);
+				make_state_lockfile = NULL;
+				make_state_locked = false;
+			}
+			fatal(catgets(catd, 1, 63, "Giving up on writing statefile"));
+		}
+		sleep(10);
+		(void) sprintf(buffer, NOCATGETS("%s/.make.state.%d.XXXXXX"), tmpdir, getpid());
+		int fdes = mkstemp(buffer);
+		if ((fdes < 0) || (fd = fdopen(fdes, "w")) == NULL) {
+			fatal(catgets(catd, 1, 64, "Could not open statefile `%s': %s"),
+			      buffer,
+			      errmsg(errno));
+		}
+		warning(catgets(catd, 1, 65, "Initial write of statefile failed. Trying again on %s"),
+			buffer);
+	}
+
+	/* Write the version stamp. */
+	XFWRITE(make_version->string_mb,
+		strlen(make_version->string_mb),
+		fd);
+	XPUTC(colon_char, fd);
+	XPUTC(tab_char, fd);
+	XFWRITE(current_make_version->string_mb,
+		strlen(current_make_version->string_mb),
+		fd);
+	XPUTC(newline_char, fd);
+
+	/*
+	 * Go through all the targets, dump their dependencies and
+	 * command used.
+	 */
+	for (np = hashtab.begin(), e = hashtab.end(); np != e; np++) {
+		/*
+		 * If the target has no command used nor dependencies,
+		 * we can go to the next one.
+		 */
+		if ((lines = get_prop(np->prop, line_prop)) == NULL) {
+			continue;
+		}
+		/* If this target is a special target, don't print. */
+		if (np->special_reader != no_special) {
+			continue;
+		}
+		/*
+		 * Find out if any of the targets dependencies should
+		 * be written to .make.state.
+		 */
+		for (m = 0, dependency = lines->body.line.dependencies;
+		     dependency != NULL;
+		     dependency = dependency->next) {
+			if (m = !dependency->stale
+			    && (dependency->name != force)
+#ifndef PRINT_EXPLICIT_DEPEN
+			    && dependency->automatic
+#endif
+			    ) {
+				break;
+			}
+		}
+		/* Only print if dependencies listed. */
+		if (m || (lines->body.line.command_used != NULL)) {
+			name_printed = false;
+			/*
+			 * If this target was built during this make run,
+			 * we mark it.
+			 */
+			built_this_run = false;
+			if (np->has_built) {
+				built_this_run = true;
+				XFWRITE(built_last_make_run->string_mb,
+					strlen(built_last_make_run->string_mb),
+					fd);
+				XPUTC(colon_char, fd);
+				XPUTC(newline_char, fd);
+			}
+			/* If the target has dependencies, we dump them. */
+			target_name = escape_target_name(np);
+			if (np->has_long_member_name) {
+				target_name =
+				  get_prop(np->prop, long_member_name_prop)
+				    ->body.long_member_name.member_name->
+				      string_mb;
+			}
+			if (m) {
+				XFPUTS(target_name, fd);
+				XPUTC(colon_char, fd);
+				XFPUTS("\t", fd);
+				name_printed = true;
+				line_length = 0;
+				for (dependency =
+				     lines->body.line.dependencies;
+				     dependency != NULL;
+				     dependency = dependency->next) {
+					print_auto_depes(dependency,
+							 fd,
+							 built_this_run,
+							 &line_length,
+							 target_name,
+							 long_jump);
+				}
+				XFPUTS("\n", fd);
+			}
+			/* If there is a command used, we dump it. */
+			if (lines->body.line.command_used != NULL) {
+				/*
+				 * Only write the target name if it
+				 * wasn't done for the dependencies.
+				 */
+				if (!name_printed) {
+					XFPUTS(target_name, fd);
+					XPUTC(colon_char, fd);
+					XPUTC(newline_char, fd);
+				}
+				/*
+				 * Write the command lines.
+				 * Prefix each textual line with a tab.
+				 */
+				for (cp = lines->body.line.command_used;
+				     cp != NULL;
+				     cp = cp->next) {
+					char		*csp;
+					int		n;
+
+					XPUTC(tab_char, fd);
+					if (cp->command_line != NULL) {
+						for (csp = cp->
+						           command_line->
+						           string_mb,
+						     n = strlen(cp->
+						                command_line->
+						                string_mb);
+						     n > 0;
+						     n--, csp++) {
+							XPUTC(*csp, fd);
+							if (*csp ==
+							    (int) newline_char) {
+								XPUTC(tab_char,
+								      fd);
+							}
+						}
+					}
+					XPUTC(newline_char, fd);
+				}
+			}
+			(void)free(target_name);
+		}
+	}
+	if (fclose(fd) == EOF) {
+		longjmp(long_jump, LONGJUMP_VALUE);
+	}
+	if (attempts == 0) {
+		if (unlink(make_state->string_mb) != 0 && errno != ENOENT) {
+			lock_err = errno; /* Save it! unlink() can change errno */
+			/* Delete temporary statefile */
+			(void) unlink(make_state_tempfile);
+			(void) unlink(make_state_lockfile);
+	 		retmem_mb(make_state_lockfile);
+			make_state_lockfile = NULL;
+			make_state_locked = false;
+			fatal(catgets(catd, 1, 356, "Could not delete old statefile `%s': %s"),
+			      make_state->string_mb,
+			      errmsg(lock_err));
+		}
+		if (rename(make_state_tempfile, make_state->string_mb) != 0) {
+			lock_err = errno; /* Save it! unlink() can change errno */
+			/* Delete temporary statefile */
+			(void) unlink(make_state_tempfile);
+			(void) unlink(make_state_lockfile);
+	 		retmem_mb(make_state_lockfile);
+			make_state_lockfile = NULL;
+			make_state_locked = false;
+			fatal(catgets(catd, 1, 357, "Could not rename `%s' to `%s': %s"),
+			      make_state_tempfile,
+			      make_state->string_mb,
+			      errmsg(lock_err));
+		}
+	}
+	if ((make_state_lockfile != NULL) && make_state_locked) {
+		(void) unlink(make_state_lockfile);
+ 		retmem_mb(make_state_lockfile);
+		make_state_lockfile = NULL;
+		make_state_locked = false;
+	}
+#ifdef NSE
+	if (report_recursive) {
+		report_recursive_done();
+	}
+#endif
+}
+
+/*
+ *	print_auto_depes(dependency, fd, built_this_run,
+ *			 line_length, target_name, long_jump)
+ *
+ *	Will print a dependency list for automatic entries.
+ *
+ *	Parameters:
+ *		dependency	The dependency to print
+ *		fd		The file to print it to
+ *		built_this_run	If on we prefix each line with .BUILT_THIS...
+ *		line_length	Pointer to line length var that we update
+ *		target_name	We need this when we restart line
+ *		long_jump	setjmp/longjmp buffer used for IO error action
+ *
+ *	Global variables used:
+ *		built_last_make_run The Name ".BUILT_LAST_MAKE_RUN", written
+ *		force		The Name " FORCE", compared against
+ */
+static void
+print_auto_depes(register Dependency dependency, register FILE *fd, register Boolean built_this_run, register int *line_length, register char *target_name, jmp_buf long_jump)
+{
+	if (!dependency->automatic ||
+	    dependency->stale ||
+	    (dependency->name == force)) {
+		return;
+	}
+	XFWRITE(dependency->name->string_mb, 
+		strlen(dependency->name->string_mb),
+		fd);
+	/*
+	 * Check if the dependency line is too long.
+	 * If so, break it and start a new one.
+	 */
+	if ((*line_length += (int) strlen(dependency->name->string_mb) + 1) > 450) {
+		*line_length = 0;
+		XPUTC(newline_char, fd);
+		if (built_this_run) {
+			XFPUTS(built_last_make_run->string_mb, fd);
+			XPUTC(colon_char, fd);
+			XPUTC(newline_char, fd);
+		}
+		XFPUTS(target_name, fd);
+		XPUTC(colon_char, fd);
+		XPUTC(tab_char, fd);
+	} else {
+		XFPUTS(" ", fd);
+	}
+	return;
+}
+
+
--- /dev/null	2015-05-20 11:04:11.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/common/svr4.make.rules.file	2015-05-20 11:04:11.688792290 -0400
@@ -0,0 +1,242 @@
+#
+# 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 1994 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)svr4.make.rules.file 1.4 06/12/12
+#
+.SUFFIXES: .o .c .c~ .y .y~ .l .l~ .s .s~ .sh .sh~ .h .h~ .f .f~ \
+.C .C~ .Y .Y~ .L .L~
+
+MAKE=make
+BUILD=build
+AR=ar
+ARFLAGS=rv
+AS=as
+ASFLAGS=
+CC=cc
+CFLAGS=-O
+F77=f77
+FFLAGS=-O
+GET=get
+GFLAGS=
+LD=ld
+LDFLAGS=
+LEX=lex
+LFLAGS=
+YACC=yacc
+YFLAGS=
+C++C=CC
+C++FLAGS=-O
+
+
+.c:
+	$(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)
+.c~:
+	$(GET) $(GFLAGS) $<
+	$(CC) $(CFLAGS) $*.c -o $@ $(LDFLAGS)
+	-rm -f $*.c
+.f:
+	$(F77) $(FFLAGS) $< -o $@ $(LDFLAGS)
+.f~:
+	$(GET) $(GFLAGS) $<
+	$(F77) $(FFLAGS) $*.f -o $@ $(LDFLAGS)
+	-rm -f $*.f
+.s:
+	$(AS) $(ASFLAGS) $< -o $@ $(LDFLAGS)
+.s~:
+	$(GET) $(GFLAGS) $<
+	$(AS) $(ASFLAGS) $*.s -o $* $(LDFLAGS)
+	-rm -f $*.s
+.sh:
+	cp $< $@; chmod 0777 $@
+.sh~:
+	$(GET) $(GFLAGS) $<
+	cp $*.sh $*; chmod 0777 $@
+	-rm -f $*.sh
+.C:
+	$(C++C) $(C++FLAGS) $< -o $@ $(LDFLAGS)
+.C~:
+	$(GET) $(GFLAGS) $<
+	$(C++C) $(C++FLAGS) $*.C -o $@ $(LDFLAGS)
+	-rm -f $*.C
+
+.c.a:
+	$(CC) $(CFLAGS) -c $<
+	$(AR) $(ARFLAGS) $@ $*.o
+	-rm -f $*.o
+.c.o:
+	$(CC) $(CFLAGS) -c $<
+.c~.a:
+	$(GET) $(GFLAGS) $<
+	$(CC) $(CFLAGS) -c $*.c
+	$(AR) $(ARFLAGS) $@ $*.o
+	-rm -f $*.[co]
+.c~.c:
+	$(GET) $(GFLAGS) $<
+.c~.o:
+	$(GET) $(GFLAGS) $<
+	$(CC) $(CFLAGS) -c $*.c
+	-rm -f $*.c
+.f.a:
+	$(F77) $(FFLAGS) -c $*.f
+	$(AR) $(ARFLAGS) $@ $*.o
+	-rm -f $*.o
+.f.o:
+	$(F77) $(FFLAGS) -c $*.f
+.f~.a:
+	$(GET) $(GFLAGS) $<
+	$(F77) $(FFLAGS) -c $*.f
+	$(AR) $(ARFLAGS) $@ $*.o
+	-rm -f $*.[fo]
+.f~.f:
+	$(GET) $(GFLAGS) $<
+.f~.o:
+	$(GET) $(GFLAGS) $<
+	$(F77) $(FFLAGS) -c $*.f
+	-rm -f $*.f
+.h~.h:
+	$(GET) $(GFLAGS) $<
+.l.c:
+	$(LEX) $(LFLAGS) $<
+	mv lex.yy.c $@
+.l.o:
+	$(LEX) $(LFLAGS) $<
+	$(CC) $(CFLAGS) -c lex.yy.c
+	-rm lex.yy.c; mv lex.yy.o $@
+.l~.c:
+	$(GET) $(GFLAGS) $<
+	$(LEX) $(LFLAGS) $*.l
+	mv lex.yy.c $@
+	-rm -f $*.l
+.l~.l:
+	$(GET) $(GFLAGS) $<
+.l~.o:
+	$(GET) $(GFLAGS) $<
+	$(LEX) $(LFLAGS) $*.l
+	$(CC) $(CFLAGS) -c lex.yy.c
+	-rm -f lex.yy.c $*.l
+	mv lex.yy.o $@
+.s.a:
+	$(AS) $(ASFLAGS) -o $*.o $*.s
+	$(AR) $(ARFLAGS) $@ $*.o
+.s.o:
+	$(AS) $(ASFLAGS) -o $@ $<
+.s~.a:
+	$(GET) $(GFLAGS) $<
+	$(AS) $(ASFLAGS) -o $*.o $*.s
+	$(AR) $(ARFLAGS) $@ $*.o
+	-rm -f $*.[so]
+.s~.o:
+	$(GET) $(GFLAGS) $<
+	$(AS) $(ASFLAGS) -o $*.o $*.s
+	-rm -f $*.s
+.s~.s:
+	$(GET) $(GFLAGS) $<
+.sh~.sh:
+	$(GET) $(GFLAGS) $<
+.y.c:
+	$(YACC) $(YFLAGS) $<
+	mv y.tab.c $@
+.y.o:
+	$(YACC) $(YFLAGS) $<
+	$(CC) $(CFLAGS) -c y.tab.c
+	-rm y.tab.c
+	mv y.tab.o $@
+.y~.c:
+	$(GET) $(GFLAGS) $<
+	$(YACC) $(YFLAGS) $*.y
+	mv y.tab.c $*.c
+	-rm -f $*.y
+.y~.o:
+	$(GET) $(GFLAGS) $<
+	$(YACC) $(YFLAGS) $*.y
+	$(CC) $(CFLAGS) -c y.tab.c
+	-rm -f y.tab.c $*.y
+	mv y.tab.o $*.o
+.y~.y :
+	$(GET) $(GFLAGS) $<
+.C.a:
+	$(C++C) $(C++FLAGS) -c $<
+	$(AR) $(ARFLAGS) $@ $*.o
+	-rm -f $*.o
+.C.o:
+	$(C++C) $(C++FLAGS) -c $<
+.C~.a:
+	$(GET) $(GFLAGS) $<
+	$(C++C) $(C++FLAGS) -c $*.C
+	$(AR) $(ARFLAGS) $@ $*.o
+	-rm -f $*.[Co]
+.C~.C:
+	$(GET) $(GFLAGS) $<
+.C~.o:
+	$(GET) $(GFLAGS) $<
+	$(C++C) $(C++FLAGS) -c $*.C
+	-rm -f $*.C
+.L.C:
+	$(LEX) $(LFLAGS) $<
+	mv lex.yy.c $@
+.L.o:
+	$(LEX) $(LFLAGS) $<
+	$(C++C) $(C++FLAGS) -c lex.yy.c
+	-rm lex.yy.c; mv lex.yy.o $@
+.L~.C:
+	$(GET) $(GFLAGS) $<
+	$(LEX) $(LFLAGS) $*.L
+	mv lex.yy.c $@
+	-rm -f $*.L
+.L~.L:
+	$(GET) $(GFLAGS) $<
+.L~.o:
+	$(GET) $(GFLAGS) $<
+	$(LEX) $(LFLAGS) $*.L
+	$(C++C) $(C++FLAGS) -c lex.yy.c
+	-rm -f lex.yy.c $*.L
+	mv lex.yy.c $@
+.Y.C:
+	$(YACC) $(YFLAGS) $<
+	mv y.tab.c $@
+.Y.o:
+	$(YACC) $(YFLAGS) $<
+	$(C++C) $(C++FLAGS) -c y.tab.c
+	-rm y.tab.c
+	mv y.tab.o $@
+.Y~.C:
+	$(GET) $(GFLAGS) $<
+	$(YACC) $(YFLAGS) $*.Y
+	mv y.tab.c $*.C
+	-rm -f $*.Y
+.Y~.o:
+	$(GET) $(GFLAGS) $<
+	$(YACC) $(YFLAGS) $*.Y
+	$(C++C) $(C++FLAGS) -c y.tab.c
+	-rm -f y.tab.c $*.Y
+	mv y.tab.o $*.o
+.Y~.Y :
+	$(GET) $(GFLAGS) $<
+
+markfile.o:	markfile
+	echo "static char _sccsid[] = \"`grep @'(#)' markfile`\";" > markfile.c
+	$(CC) -c markfile.c
+	-rm -f markfile.c
+
+.SCCS_GET:
+	$(GET) $(GFLAGS)  s.$@
--- /dev/null	2015-05-20 11:04:11.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/make.svr4/Makefile	2015-05-20 11:04:11.881307694 -0400
@@ -0,0 +1,38 @@
+#
+# 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 2001 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.6 06/12/12
+#
+
+TOP=../../../..
+include $(TOP)/rules/master.mk
+
+all clean clobber l10n_install:
+
+install:
+	$(INSTALL) -d $(DESTDIR)/usr/lib
+	$(INSTALL) -d $(DESTDIR)/usr/ccs/lib
+	rm -f $(DESTDIR)/usr/lib/svr4.make
+	rm -f $(DESTDIR)/usr/ccs/lib/svr4.make
+	ln $(DESTDIR)/usr/ccs/bin/make $(DESTDIR)/usr/lib/svr4.make
+	(cd $(DESTDIR)/usr/ccs/lib; ln -s ../../lib/svr4.make svr4.make)
--- /dev/null	2015-05-20 11:04:12.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/make.xpg4/Makefile	2015-05-20 11:04:12.135016200 -0400
@@ -0,0 +1,36 @@
+#
+# 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 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.2 06/12/12
+#
+# @(#)Makefile	1.1	95/06/29 SMI
+
+TOP=../../../..
+include $(TOP)/rules/master.mk
+
+all clean clobber l10n_install:
+
+install:
+	$(INSTALL) -d $(DESTDIR)/usr/xpg4/bin
+	rm -f $(DESTDIR)/usr/xpg4/bin/make
+	ln $(DESTDIR)/usr/ccs/bin/make $(DESTDIR)/usr/xpg4/bin/make
--- /dev/null	2015-05-20 11:04:12.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/smake/Makefile	2015-05-20 11:04:12.868956022 -0400
@@ -0,0 +1,30 @@
+#
+# 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 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.5 06/12/12
+#
+
+TOP		= ../../../..
+include $(TOP)/rules/variant.mk
+include $(TOP)/rules/derived.mk
+
--- /dev/null	2015-05-20 11:04:13.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/smake/src/Makefile	2015-05-20 11:04:13.066816455 -0400
@@ -0,0 +1,50 @@
+#
+# 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 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.3 06/12/12
+#
+
+# Generic makefile for use in src directories.  Knows how to make common things
+# in the right $(VARIANT) directory.
+
+#TOP =		../../../../..
+include $(TOP)/rules/variant.mk
+
+all :=		TARG = all 
+install :=		TARG = install 
+clean :=		TARG = clean 
+test :=		TARG = test
+l10n_install :=	TARG = l10n_install
+i18n_install :=	TARG = i18n_install
+
+SRC =		../src
+MFLAGS += 	SRC=$(SRC)
+
+# See $(TOP)/rules/master.mk for how these are built.
+%.h %.cc %.C %.E %.o all install clean test l10n_install i18n_install: FRC
+	@ if [ ! -d ../$(VARIANT) ]; then \
+		mkdir ../$(VARIANT) ; \
+	fi
+	cd ../$(VARIANT); $(MAKE) $(MFLAGS) -f $(SRC)/Variant.mk DESTDIR=$(DESTDIR) $@
+
+FRC:
--- /dev/null	2015-05-20 11:04:13.000000000 -0400
+++ new/usr/src/cmd/make/bin/make/smake/src/Variant.mk	2015-05-20 11:04:13.259492664 -0400
@@ -0,0 +1,155 @@
+#
+# 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 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Variant.mk 1.36 06/12/12
+#
+
+TOP		= ../../../../..
+include $(TOP)/rules/master.mk
+include $(TOP)/Make/lib/Lib.mk
+
+# RELEASE_VER should be "Generic" for FCS. Otherwise it should be overridden
+# to display build number - "Build XX", patch number - "Patch XXXXXX-XX", etc.
+
+PKG_TOP		= ../../../..
+PROG		= make
+PACKAGE		= SUNWspro
+PRODVER		= 11
+PRODVER_V	= SunOS 5.11
+RELEASE_VER	= Generic
+DATE:sh		= date '+%B %Y'
+
+VERSTRING	= RELEASE VERSION $(PRODVER_V) $(RELEASE_VER) $(DATE)
+
+MORE_SRC	= \
+		ar.cc \
+		depvar.cc \
+		doname.cc \
+		dosys.cc \
+		files.cc \
+		globals.cc \
+		implicit.cc \
+		macro.cc \
+		main.cc \
+		misc.cc \
+		nse_printdep.cc \
+		read.cc \
+		read2.cc \
+		rep.cc \
+		state.cc
+
+CPPFLAGS	+= -I$(PKG_TOP)/include
+
+LDLIB		+= \
+		-lnsl \
+		-lsocket \
+		-lw
+
+HDRS_DIR	= $(PKG_TOP)/include/mk
+HDRS_LIST	= $(HDRS_DIR)/copyright.h $(HDRS_DIR)/defs.h
+
+.INIT: $(HDRS_LIST)
+
+SRCS = $(PROG).cc $(MORE_SRC)
+OBJS = $(SRCS:%.cc=%.o)
+
+LIB +=		-lintl -lm
+
+all install:: $(PROG)
+
+$(PROG): $(OBJS)
+	$(CCC) $(CCFLAGS) $(LDFLAGS) -o $@ \
+		$(OBJS) $(LIB) $(I18LIB) $(LDLIB)
+	/bin/sh $(TOP)/exe/sanity-check.sh $(TOP) $(PROG)
+
+clean:
+	$(RM) $(OBJS) $(PROG)
+
+
+include $(TOP)/rules/computed-options.mk
+
+#
+# This LIB macro must be declared after the include's above
+#
+LIB		= \
+		$(LIBMKSH) \
+		$(LIBMKSDMSI18N) \
+		$(LIBBSD) \
+		$(LIBVROOT)
+
+%.o: ../../common/%.cc
+	$(COMPILE.cc) $(OUTPUT_OPTION) $<
+
+depvar.o nse.o nse_printdep.o := CPPFLAGS += -DSUNOS4_AND_AFTER
+
+LDFLAGS +=	-xildoff -norunpath
+
+install:: install-make-hdrs install-make-bin
+
+IHDR		= make.rules.file
+VIHDR		= svr4.make.rules.file
+HDR		= ${PKG_TOP}/bin/make/common/make.rules.file
+VHDR		= ${PKG_TOP}/bin/make/common/svr4.make.rules.file
+HDRSDIR		= $(DESTDIR)/usr/share/lib/make
+HDRFILE		= make.rules
+VHDRFILE	= svr4.make.rules
+SMAKEDIR	= $(DESTDIR)/usr/ccs/bin
+
+install-make-bin: make
+	$(INSTALL) -d $(SMAKEDIR)
+	$(INSTALL) make $(SMAKEDIR) 
+	mcs -d $(SMAKEDIR)/make
+	mcs -a '@(#)$(VERSTRING)' $(SMAKEDIR)/make
+
+install-make-hdrs: $(HDR) $(VHDR)
+	$(INSTALL) -d $(HDRSDIR)
+	$(INSTALL) -m 0444 $(HDR) $(HDRSDIR)
+	mv -f $(HDRSDIR)/$(IHDR) $(HDRSDIR)/$(HDRFILE)
+	$(INSTALL) -m 0444 $(VHDR) $(HDRSDIR)
+	mv -f $(HDRSDIR)/$(VIHDR) $(HDRSDIR)/$(VHDRFILE)
+
+
+#
+# i18n stuff
+#
+MAKE_MSG	= SUNW_SPRO_MAKE.msg
+#I18N_DIRS	= ../../common ../../../../lib/bsd/src ../../../../lib/mksh/src ../../../../lib/vroot/src
+I18N_DIRS	= ../../common
+TEXTDOMAIN	= SUNW_SPRO_MAKE
+APPPATH		= $(PKG_TOP)/bin/make/smake/$(VARIANT)
+LIB_DESTDIR	= $(DESTDIR)/usr/lib
+CAT_DESTDIR	= $(LIB_DESTDIR)/locale/C/LC_MESSAGES
+
+$(CAT_DESTDIR):
+	$(INSTALL) -d $@
+
+msg_catalogs: $(CAT_DESTDIR) .WAIT MAKE_MSG
+	cp $(APPPATH)/$(TEXTDOMAIN).msg $(CAT_DESTDIR)
+
+MAKE_MSG:
+	$(GENMSG) -l $(SRC)/genmsg.project -o $(TEXTDOMAIN).msg `find $(I18N_DIRS) \( -name '*.cc' -o -name '*.c' -o -name '*.y' -o -name '*.h' \) -print | grep -v /SCCS/`
+	rm -f *.cc.new
+
+i18n_install: msg_catalogs 
+
+FRC:
--- /dev/null	2015-05-20 11:04:13.000000000 -0400
+++ new/usr/src/cmd/make/include/avo/avo_alloca.h	2015-05-20 11:04:13.464449547 -0400
@@ -0,0 +1,49 @@
+/*
+ * 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 1998 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)avo_alloca.h 1.4 06/12/12
+ */
+
+#pragma ident   "@(#)avo_alloca.h 1.4     06/12/12"
+
+#ifndef _AVO_ALLOCA_H
+#define _AVO_ALLOCA_H
+
+#include <alloca.h>
+
+#ifdef __SunOS_5_4
+// The following prototype declaration is necessary when compiling on Solaris
+// 2.4 using 5.0 compilers. On Solaris 2.4 the necessary prototypes are not
+// included in alloca.h. The 4.x compilers provide a workaround by declaring the
+// prototype as a pre-defined type. The 5.0 compilers do not implement this workaround.
+// This can be removed when support for 2.4 is dropped
+
+#include <stdlib.h> 	// for size_t
+extern "C" void *__builtin_alloca(size_t);
+
+#endif  // ifdef __SunOS_5_4
+
+#endif  // ifdef _AVO_ALLOCA_H
+
--- /dev/null	2015-05-20 11:04:13.000000000 -0400
+++ new/usr/src/cmd/make/include/avo/intl.h	2015-05-20 11:04:13.651425425 -0400
@@ -0,0 +1,77 @@
+/*
+ * 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 2001 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)intl.h 1.19 06/12/12
+ */
+
+#pragma	ident	"@(#)intl.h	1.19	06/12/12"
+
+#ifndef _AVO_INTL_H
+#define _AVO_INTL_H
+
+#if defined(SUN4_x) || defined(HP_UX)
+#include <avo/widefake.h>
+#endif
+
+/* 
+ * For catgets
+ */
+#include <nl_types.h>
+
+#ifdef HP_UX
+#ifdef __cplusplus
+#ifndef _STDLIB_INCLUDED
+#include <stdlib.h>             /* for wchar_t definition and HP-UX - */
+#endif                          /* wide character function prototypes. */
+extern "C" {
+char *gettext(char *msg);
+char *dgettext(const char *, const char *);
+char *bindtextdomain(const char *, const char *);
+char *textdomain(char *);
+}
+#endif /* __cplusplus */
+#endif
+
+/*
+ * NOCATGETS is a dummy macro that returns it argument.
+ * It is used to identify strings that we consciously do not
+ * want to apply catgets() to.  We have tools that check the
+ * sources for strings that are not catgets'd and the tools
+ * ignore strings that are NOCATGETS'd.
+ */
+#define	NOCATGETS(str)	(str)
+
+/*
+ * Define the various text domains
+ */
+#define	AVO_DOMAIN_CODEMGR	"codemgr"
+#define AVO_DOMAIN_VERTOOL	"vertool"
+#define AVO_DOMAIN_FILEMERGE	"filemerge"
+#define AVO_DOMAIN_DMAKE	"dmake"
+#define AVO_DOMAIN_PMAKE	"pmake"
+#define AVO_DOMAIN_FREEZEPOINT	"freezept"
+#define AVO_DOMAIN_MAKETOOL	"maketool"
+
+#endif
--- /dev/null	2015-05-20 11:04:13.000000000 -0400
+++ new/usr/src/cmd/make/include/bsd/bsd.h	2015-05-20 11:04:13.850557398 -0400
@@ -0,0 +1,58 @@
+/*
+ * 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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)bsd.h 1.6 06/12/12
+ */
+
+#pragma	ident	"@(#)bsd.h	1.6	06/12/12"
+
+/*
+ * bsd/bsd.h: Interface definitions to BSD compatibility functions for SVR4.
+ */
+
+#ifndef _BSD_BSD_H
+#define _BSD_BSD_H
+
+#include <signal.h>
+
+#if defined (HP_UX) || defined (linux)
+typedef void SIG_FUNC_TYP(int);
+typedef SIG_FUNC_TYP *SIG_TYP;
+#define SIG_PF SIG_TYP
+#endif
+
+#ifndef __cplusplus
+typedef void (*SIG_PF) (int);
+#endif
+
+#ifdef __cplusplus
+extern "C" SIG_PF bsd_signal(int a, SIG_PF b);
+#else
+extern void (*bsd_signal(int, void (*) (int))) (int);
+#endif
+extern void bsd_signals(void);
+
+#endif
+
--- /dev/null	2015-05-20 11:04:14.000000000 -0400
+++ new/usr/src/cmd/make/include/mk/copyright.h	2015-05-20 11:04:14.062197131 -0400
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+/*
+ * @(#)copyright.h 1.11 06/12/12
+ */
--- /dev/null	2015-05-20 11:04:14.000000000 -0400
+++ new/usr/src/cmd/make/include/mk/defs.h	2015-05-20 11:04:14.250466044 -0400
@@ -0,0 +1,495 @@
+#ifndef _MK_DEFS_H
+#define _MK_DEFS_H
+/*
+ * 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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)defs.h 1.61 06/12/12
+ */
+
+#pragma	ident	"@(#)defs.h	1.61	06/12/12"
+
+/*
+ * Included files
+ */
+#ifdef DISTRIBUTED
+#	include <dm/Avo_AcknowledgeMsg.h>
+#	include <dm/Avo_DoJobMsg.h>
+#	include <dm/Avo_JobResultMsg.h>
+#endif
+
+#include <mksh/defs.h>
+
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+#	include <rw/xdrstrea.h>
+#endif
+
+
+/*
+ * Defined macros
+ */
+
+#define SKIPSPACE(x)	while (*x &&				\
+			       ((*x == (int) space_char) ||	\
+			        (*x == (int) tab_char) ||	\
+			        (*x == (int) comma_char))) {	\
+					x++;			\
+			}
+
+#define SKIPWORD(x)	while (*x &&				\
+			       (*x != (int) space_char) &&	\
+			       (*x != (int) tab_char) &&	\
+			       (*x != (int) newline_char) &&	\
+			       (*x != (int) comma_char) &&	\
+			       (*x != (int) equal_char)) {	\
+					x++;			\
+			}
+
+#define SKIPTOEND(x)	while (*x &&				\
+			       (*x != (int) newline_char)) {	\
+					x++;			\
+			}
+
+#define PMAKE_DEF_MAX_JOBS	2	/* Default number of parallel jobs. */
+
+#define OUT_OF_DATE(a,b) \
+	(((a) < (b)) || (((a) == file_doesnt_exist) && ((b) == file_doesnt_exist)))
+
+#define OUT_OF_DATE_SEC(a,b) \
+	(((a).tv_sec < (b).tv_sec) || (((a).tv_sec == file_doesnt_exist.tv_sec) && ((b).tv_sec == file_doesnt_exist.tv_sec)))
+	
+#define SETVAR(name, value, append) \
+				setvar_daemon(name, value, append, no_daemon, \
+					      true, debug_level)
+#ifdef SUN5_0
+#define MAX(a,b)		(((a)>(b))?(a):(b))
+/*
+ * New feature added to SUN5_0 make,  invoke the vanilla svr4 make when
+ * the USE_SVR4_MAKE environment variable is set.
+ */
+#define SVR4_MAKE		"/usr/ccs/lib/svr4.make"
+#define USE_SVR4_MAKE		"USE_SVR4_MAKE"
+#endif
+/*
+ * The standard MAXHOSTNAMELEN is 64. We want 32.
+ */
+#define	MAX_HOSTNAMELEN		32
+
+
+/*
+ * typedefs & structs
+ */
+typedef enum {
+	no_state,
+	scan_name_state,
+	scan_command_state,
+	enter_dependencies_state,
+	enter_conditional_state,
+	enter_equal_state,
+	illegal_bytes_state,
+	illegal_eoln_state,
+	poorly_formed_macro_state,
+	exit_state
+}                       Reader_state;
+
+struct _Name_vector {
+	struct _Name		*names[64];
+	struct _Chain		*target_group[64];
+	short                   used;
+	struct _Name_vector	*next;
+};
+
+struct _Running {
+	struct _Running		*next;
+	Doname			state;
+	struct _Name		*target;
+	struct _Name		*true_target;
+	struct _Property	*command;
+	struct _Name		*sprodep_value;
+	char			*sprodep_env;
+	int			recursion_level;
+	Boolean			do_get;
+	Boolean			implicit;
+	Boolean			redo;
+	int			auto_count;
+	struct _Name		**automatics;
+	pid_t			pid;
+#ifdef TEAMWARE_MAKE_CMN
+	int			job_msg_id;
+#else
+	int			host;
+#endif
+	char			*stdout_file;
+	char			*stderr_file;
+	struct _Name		*temp_file;
+	int			conditional_cnt;
+	struct _Name		**conditional_targets;
+#ifdef TEAMWARE_MAKE_CMN
+	Boolean			make_refd;
+#endif
+};
+
+typedef enum {
+	serial_mode,
+	parallel_mode,
+	distributed_mode
+} DMake_mode;
+
+typedef enum {
+	txt1_mode,
+	txt2_mode,
+	html1_mode
+} DMake_output_mode;
+
+struct _Recursive_make {
+	struct _Recursive_make	*next;	/* Linked list */
+	wchar_t			*target;/* Name of target */
+	wchar_t			*oldline;/* Original line in .nse_depinfo */
+	wchar_t			*newline;/* New line in .nse_depinfo */
+	wchar_t			*cond_macrostring; 
+					/* string built from value of 
+					 * conditional macros used by 
+					 * this target
+					 */
+	Boolean			removed;/* This target is no longer recursive*/
+};
+
+struct _Dyntarget {
+	struct _Dyntarget	*next;
+	struct _Name		*name;
+};
+
+
+/*
+ * Typedefs for all structs
+ */
+typedef struct _Cmd_line	*Cmd_line, Cmd_line_rec;
+typedef struct _Dependency	*Dependency, Dependency_rec;
+typedef struct _Macro		*Macro, Macro_rec;
+typedef struct _Name_vector	*Name_vector, Name_vector_rec;
+typedef struct _Percent		*Percent, Percent_rec;
+typedef struct _Dyntarget	*Dyntarget;
+typedef struct _Recursive_make	*Recursive_make, Recursive_make_rec;
+typedef struct _Running		*Running, Running_rec;
+
+
+/*
+ *	extern declarations for all global variables.
+ *	The actual declarations are in globals.cc
+ */
+extern	Boolean		allrules_read;
+extern	Name		posix_name;
+extern	Name		svr4_name;
+extern	Boolean		sdot_target;
+extern	Boolean		all_parallel;
+extern	Boolean		assign_done;
+extern	Boolean		build_failed_seen;
+#ifdef DISTRIBUTED
+extern	Boolean		building_serial;
+#endif
+extern	Name		built_last_make_run;
+extern	Name		c_at;
+#ifdef DISTRIBUTED
+extern	Boolean		called_make;
+#endif
+extern	Boolean		command_changed;
+extern	Boolean		commands_done;
+extern	Chain		conditional_targets;
+extern	Name		conditionals;
+extern	Boolean		continue_after_error;
+extern	Property	current_line;
+extern	Name		current_make_version;
+extern	Name		current_target;
+extern	short		debug_level;
+extern	Cmd_line	default_rule;
+extern	Name		default_rule_name;
+extern	Name		default_target_to_build;
+extern	Boolean		depinfo_already_read;
+extern	Name		dmake_group;
+extern	Name		dmake_max_jobs;
+extern	Name		dmake_mode;
+extern	DMake_mode	dmake_mode_type;
+extern	Name		dmake_output_mode;
+extern	DMake_output_mode	output_mode;
+extern	Name		dmake_odir;
+extern	Name		dmake_rcfile;
+extern	Name		done;
+extern	Name		dot;
+extern	Name		dot_keep_state;
+extern	Name		dot_keep_state_file;
+extern	Name		empty_name;
+extern	Boolean		fatal_in_progress;
+extern	int		file_number;
+extern	Name		force;
+extern	Name		ignore_name;
+extern	Boolean		ignore_errors;
+extern	Boolean		ignore_errors_all;
+extern	Name		init;
+extern	int		job_msg_id;
+extern	Boolean		keep_state;
+extern	Name		make_state;
+#ifdef TEAMWARE_MAKE_CMN
+extern	timestruc_t	make_state_before;
+#endif
+extern	Boolean		make_state_locked;
+extern	Dependency	makefiles_used;
+extern	Name		makeflags;
+extern	Name		make_version;
+extern	char		mbs_buffer2[];
+extern	char		*mbs_ptr;
+extern	char		*mbs_ptr2;
+extern	Boolean		no_action_was_taken;
+extern	int		mtool_msgs_fd;
+extern	Boolean		no_parallel;
+#ifdef SGE_SUPPORT
+extern	Boolean		grid;
+#endif
+extern	Name		no_parallel_name;
+extern	Name		not_auto;
+extern	Boolean		only_parallel;
+extern	Boolean		parallel;
+extern	Name		parallel_name;
+extern	Name		localhost_name;
+extern	int		parallel_process_cnt;
+extern	Percent		percent_list;
+extern	Dyntarget	dyntarget_list;
+extern	Name		plus;
+extern	Name		pmake_machinesfile;
+extern	Name		precious;
+extern	Name		primary_makefile;
+extern	Boolean		quest;
+extern	short		read_trace_level;
+extern	Boolean		reading_dependencies;
+extern	int		recursion_level;
+extern	Name		recursive_name;
+extern	short		report_dependencies_level;
+extern	Boolean		report_pwd;
+extern	Boolean		rewrite_statefile;
+extern	Running		running_list;
+extern	char		*sccs_dir_path;
+extern	Name		sccs_get_name;
+extern	Name		sccs_get_posix_name;
+extern	Cmd_line	sccs_get_rule;
+extern	Cmd_line	sccs_get_org_rule;
+extern	Cmd_line	sccs_get_posix_rule;
+extern	Name		get_name;
+extern	Name		get_posix_name;
+extern	Cmd_line	get_rule;
+extern	Cmd_line	get_posix_rule;
+extern	Boolean		send_mtool_msgs;
+extern	Boolean		all_precious;
+extern	Boolean		report_cwd;
+extern	Boolean		silent_all;
+extern	Boolean		silent;
+extern	Name		silent_name;
+extern	char		*stderr_file;
+extern	char		*stdout_file;
+#ifdef SGE_SUPPORT
+extern	char		script_file[];
+#endif
+extern	Boolean		stdout_stderr_same;
+extern	Dependency	suffixes;
+extern	Name		suffixes_name;
+extern	Name		sunpro_dependencies;
+extern	Boolean		target_variants;
+extern	char		*tmpdir;
+extern	char		*temp_file_directory;
+extern	Name		temp_file_name;
+extern	short		temp_file_number;
+extern  wchar_t		*top_level_target;
+extern	Boolean		touch;
+extern	Boolean		trace_reader;
+extern	Boolean		build_unconditional;
+extern	pathpt		vroot_path;
+extern	Name		wait_name;
+extern	wchar_t		wcs_buffer2[];
+extern	wchar_t		*wcs_ptr;
+extern	wchar_t		*wcs_ptr2;
+extern	nl_catd		catd;
+extern	long int	hostid;
+
+/*
+ * Declarations of system defined variables
+ */
+#if !defined(linux)
+/* On linux this variable is defined in 'signal.h' */
+extern	char		*sys_siglist[];
+#endif
+
+/*
+ * Declarations of system supplied functions
+ */
+extern	int		file_lock(char *, char *, int *, int);
+
+/*
+ * Declarations of functions declared and used by make
+ */
+extern	void		add_pending(Name target, int recursion_level, Boolean do_get, Boolean implicit, Boolean redo);
+extern	void		add_running(Name target, Name true_target, Property command, int recursion_level, int auto_count, Name *automatics, Boolean do_get, Boolean implicit);
+extern	void		add_serial(Name target, int recursion_level, Boolean do_get, Boolean implicit);
+extern	void		add_subtree(Name target, int recursion_level, Boolean do_get, Boolean implicit);
+extern  void 		append_or_replace_macro_in_dyn_array(ASCII_Dyn_Array *Ar, char *macro);
+#ifdef DISTRIBUTED
+extern	Doname		await_dist(Boolean waitflg);
+#endif
+#ifdef TEAMWARE_MAKE_CMN
+extern	void		await_parallel(Boolean waitflg);
+#endif
+extern	void		build_suffix_list(Name target_suffix);
+extern	Boolean		check_auto_dependencies(Name target, int auto_count, Name *automatics);
+extern	void		check_state(Name temp_file_name);
+extern	void		cond_macros_into_string(Name np, String_rec *buffer);
+extern	void		construct_target_string();
+extern	void		create_xdrs_ptr(void);
+extern	void		depvar_add_to_list (Name name, Boolean cmdline);
+#ifdef DISTRIBUTED
+extern	void		distribute_rxm(Avo_DoJobMsg *dmake_job_msg);
+extern	int 		getRxmMessage(void);
+extern	Avo_JobResultMsg* getJobResultMsg(void);
+extern	Avo_AcknowledgeMsg* getAcknowledgeMsg(void);
+#endif
+extern	Doname		doname(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic = false);
+extern	Doname		doname_check(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic);
+extern	Doname		doname_parallel(Name target, Boolean do_get, Boolean implicit);
+extern	Doname		dosys(register Name command, register Boolean ignore_error, register Boolean call_make, Boolean silent_error, Boolean always_exec, Name target, Boolean redirect_out_err);
+extern	void		dump_make_state(void);
+extern	void		dump_target_list(void);
+extern	void		enter_conditional(register Name target, Name name, Name value, register Boolean append);
+extern	void		enter_dependencies(register Name target, Chain target_group, register Name_vector depes, register Cmd_line command, register Separator separator);
+extern	void		enter_dependency(Property line, register Name depe, Boolean automatic);
+extern	void		enter_equal(Name name, Name value, register Boolean append);
+extern  Percent		enter_percent(register Name target, Chain target_group, register Name_vector depes, Cmd_line command);
+extern	Dyntarget	enter_dyntarget(register Name target);
+extern	Name_vector	enter_name(String string, Boolean tail_present, register wchar_t *string_start, register wchar_t *string_end, Name_vector current_names, Name_vector *extra_names, Boolean *target_group_seen);
+extern	Boolean		exec_vp(register char *name, register char **argv, char **envp, register Boolean ignore_error);
+extern	Doname		execute_parallel(Property line, Boolean waitflg, Boolean local = false);
+extern	Doname		execute_serial(Property line);
+extern	timestruc_t&  	exists(register Name target);
+extern	void		fatal(char *, ...);
+extern	void		fatal_reader(char *, ...);
+extern	Doname		find_ar_suffix_rule(register Name target, Name true_target, Property *command, Boolean rechecking);
+extern	Doname		find_double_suffix_rule(register Name target, Property *command, Boolean rechecking);
+extern	Doname		find_percent_rule(register Name target, Property *command, Boolean rechecking);
+extern	int		find_run_directory (char *cmd, char *cwd, char *dir, char **pgm, char **run, char *path);
+extern	Doname		find_suffix_rule(Name target, Name target_body, Name target_suffix, Property *command, Boolean rechecking);
+extern	Chain		find_target_groups(register Name_vector target_list, register int i, Boolean reset);
+extern	void		finish_children(Boolean docheck);
+extern	void		finish_running(void);
+extern	void		free_chain(Name_vector ptr);
+extern  void		gather_recursive_deps(void);
+extern	char		*get_current_path(void);
+extern	int		get_job_msg_id(void);
+extern	FILE		*get_mtool_msgs_fp(void);
+#ifdef DISTRIBUTED
+extern	Boolean		get_dmake_group_specified(void);
+extern	Boolean		get_dmake_max_jobs_specified(void);
+extern	Boolean		get_dmake_mode_specified(void);
+extern	Boolean		get_dmake_odir_specified(void);
+extern	Boolean		get_dmake_rcfile_specified(void);
+extern	Boolean		get_pmake_machinesfile_specified(void);
+#endif
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+extern	XDR		*get_xdrs_ptr(void);
+#endif
+extern	wchar_t		*getmem_wc(register int size);
+#if !defined(linux)
+/* On linux getwd(char *) is defined in 'unistd.h' */
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern	char		*getwd(char *);
+#ifdef __cplusplus
+}
+#endif
+#endif
+extern	void		handle_interrupt(int);
+extern	Boolean		is_running(Name target);
+extern	void		load_cached_names(void);
+extern	Boolean		parallel_ok(Name target, Boolean line_prop_must_exists);
+extern	void		print_dependencies(register Name target, register Property line);
+extern	void		send_job_start_msg(Property line);
+extern	void		send_rsrc_info_msg(int max_jobs, char *hostname, char *username);
+extern	void		print_value(register Name value, Daemon daemon);
+extern	timestruc_t&	read_archive(register Name target);
+extern	int		read_dir(Name dir, wchar_t *pattern, Property line, wchar_t *library);
+extern	void		read_directory_of_file(register Name file);
+extern	int		read_make_machines(Name make_machines_name);
+extern	Boolean		read_simple_file(register Name makefile_name, register Boolean chase_path, register Boolean doname_it, Boolean complain, Boolean must_exist, Boolean report_file, Boolean lock_makefile);
+extern	void		remove_recursive_dep(Name target);
+extern	void		report_recursive_dep(Name target, char *line);
+extern	void		report_recursive_done(void);
+extern	void		report_recursive_init(void);
+extern	Recursive_make	find_recursive_target(Name target);
+extern	void		reset_locals(register Name target, register Property old_locals, register Property conditional, register int index);
+extern	void		set_locals(register Name target, register Property old_locals);
+extern	void		setvar_append(register Name name, register Name value);
+#ifdef DISTRIBUTED
+extern	void		setvar_envvar(Avo_DoJobMsg *dmake_job_msg);
+#else
+extern	void		setvar_envvar(void);
+#endif
+extern	void		special_reader(Name target, register Name_vector depes, Cmd_line command);
+extern	void		startup_rxm();
+extern	Doname		target_can_be_built(register Name target);
+extern	char		*time_to_string(const timestruc_t &time);
+extern	void		update_target(Property line, Doname result);
+extern	void		warning(char *, ...);
+extern	void		write_state_file(int report_recursive, Boolean exiting);
+extern	Name		vpath_translation(register Name cmd);
+
+#define DEPINFO_FMT_VERSION "VERS2$"
+#define VER_LEN strlen(DEPINFO_FMT_VERSION)
+
+#ifdef NSE
+
+/* 
+ *  NSE version for depinfo format
+ */
+extern Boolean		nse;
+extern Name		nse_backquote_seen;
+extern Boolean		nse_did_recursion;
+extern Name		nse_shell_var_used;
+extern Boolean		nse_watch_vars;
+extern wchar_t		current_makefile[MAXPATHLEN];
+extern Boolean		nse_depinfo_locked;
+extern char		nse_depinfo_lockfile[MAXPATHLEN];
+extern Name		derived_src;
+
+extern void		depvar_dep_macro_used(Name);
+extern void		depvar_rule_macro_used(Name);
+extern Boolean		nse_backquotes(wchar_t *);
+extern void		nse_check_cd(Property);
+extern void		nse_check_derived_src(Name, wchar_t *, Cmd_line);
+extern void		nse_check_file_backquotes(wchar_t *);
+extern void		nse_check_no_deps_no_rule(Name, Property, Property);
+extern void		nse_check_sccs(wchar_t *, wchar_t *);
+extern void		nse_dep_cmdmacro(wchar_t *);
+extern int		nse_exit_status(void);
+extern void		nse_init_source_suffixes(void);
+extern void		nse_no_makefile(Name);
+extern void		nse_rule_cmdmacro(wchar_t *);
+extern void		nse_wildcard(wchar_t *, wchar_t *);
+#endif
+
+#endif
--- /dev/null	2015-05-20 11:04:14.000000000 -0400
+++ new/usr/src/cmd/make/include/mksdmsi18n/mksdmsi18n.h	2015-05-20 11:04:14.448636386 -0400
@@ -0,0 +1,44 @@
+/*
+ * 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 1996 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)mksdmsi18n.h 1.3 06/12/12
+ */
+
+#pragma	ident	"@(#)mksdmsi18n.h	1.3	06/12/12"
+
+#ifndef _AVO_MKSDMSI18N_H
+#define _AVO_MKSDMSI18N_H
+
+#ifndef _AVO_INTL_H
+#include <avo/intl.h>
+#endif
+
+extern	nl_catd	libmksdmsi18n_catd;
+
+int	libmksdmsi18n_init();
+void	libmksdmsi18n_fini();
+
+#endif
+
--- /dev/null	2015-05-20 11:04:14.000000000 -0400
+++ new/usr/src/cmd/make/include/mksh/defs.h	2015-05-20 11:04:14.649096017 -0400
@@ -0,0 +1,1042 @@
+#ifndef _MKSH_DEFS_H
+#define _MKSH_DEFS_H
+/*
+ * 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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)defs.h 1.35 06/12/12
+ */
+
+#pragma	ident	"@(#)defs.h	1.35	06/12/12"
+
+/*
+ * This is not "#ifdef TEAMWARE_MAKE_CMN" because we're currently
+ * using the TW fake i18n headers and libraries to build both
+ * SMake and PMake on SPARC/S1 and x86/S2.
+ */
+
+#include <avo/intl.h>
+#include <limits.h>		/* MB_LEN_MAX */
+#include <stdio.h>
+#include <stdlib.h>		/* wchar_t */
+#include <string.h>		/* strcmp() */
+#include <nl_types.h>		/* catgets() */
+#include <sys/param.h>		/* MAXPATHLEN */
+#include <sys/types.h>		/* time_t, caddr_t */
+#include <vroot/vroot.h>	/* pathpt */
+#include <sys/time.h>		/* timestruc_t */
+#include <errno.h>		/* errno */
+
+#if defined (HP_UX) || defined (linux)
+#define  MAXNAMELEN           256
+#define  RW_NO_OVERLOAD_WCHAR 1  /* Rogue Wave, belongs in <rw/compiler.h> */
+#else
+#include <wctype.h>
+#include <widec.h>
+#endif
+
+#if defined (linux)
+/*
+ * Definition of wchar functions.
+ */
+#	include <wctype.h>
+#	include <wchar.h>
+#	define wsdup(x) wcsdup(x)
+#	define wschr(x,y) wcschr(x,y)
+#	define wscat(x,y) wcscat(x,y)
+#	define wsrchr(x,y) wcsrchr(x,y)
+#	define wslen(x) wcslen(x)
+#	define wscpy(x,y) wcscpy(x,y)
+#	define wsncpy(x,y,z) wcsncpy(x,y,z)
+#	define wscmp(x,y) wcscmp(x,y)
+#	define wsncmp(x,y,z) wcsncmp(x,y,z)
+#endif
+
+/*
+ * A type and some utilities for boolean values
+ */
+
+#define	false	BOOLEAN_false
+#define	true	BOOLEAN_true
+
+typedef enum {
+	false =		0,
+	true =		1,
+	failed =	0,
+	succeeded =	1
+} Boolean;
+#define BOOLEAN(expr)		((expr) ? true : false)
+
+/*
+ * Some random constants (in an enum so dbx knows their values)
+ */
+enum {
+	update_delay = 30,		/* time between rstat checks */
+#ifdef sun386
+	ar_member_name_len = 14,
+#else
+#if defined(SUN5_0) || defined(linux)
+	ar_member_name_len = 1024,
+#else
+	ar_member_name_len = 15,
+#endif
+#endif
+
+	hashsize = 2048			/* size of hash table */
+};
+
+
+/*
+ * Symbols that defines all the different char constants make uses
+ */
+enum {
+	ampersand_char =	'&',
+	asterisk_char =		'*',
+	at_char =		'@',
+	backquote_char =	'`',
+	backslash_char =	'\\',
+	bar_char =		'|',
+	braceleft_char =	'{',
+	braceright_char =	'}',
+	bracketleft_char =	'[',
+	bracketright_char =	']',
+	colon_char =		':',
+	comma_char =		',',
+	dollar_char =		'$',
+	doublequote_char =	'"',
+	equal_char =		'=',
+	exclam_char =		'!',
+	greater_char =		'>',
+	hat_char =		'^',
+	hyphen_char =		'-',
+	less_char =		'<',
+	newline_char =		'\n',
+	nul_char =		'\0',
+	numbersign_char =	'#',
+	parenleft_char =	'(',
+	parenright_char =	')',
+	percent_char =		'%',
+	period_char =		'.',
+	plus_char =		'+',
+	question_char =		'?',
+	quote_char =		'\'',
+	semicolon_char =	';',
+	slash_char =		'/',
+	space_char =		' ',
+	tab_char =		'\t',
+	tilde_char =		'~'
+};
+
+/*
+ * For make i18n. Codeset independent.
+ * Setup character semantics by identifying all the special characters
+ * of make, and assigning each an entry in the char_semantics[] vector.
+ */
+enum {
+	ampersand_char_entry = 0,	/*  0 */
+	asterisk_char_entry,		/*  1 */
+	at_char_entry,			/*  2 */
+	backquote_char_entry,		/*  3 */
+	backslash_char_entry,		/*  4 */
+	bar_char_entry,			/*  5 */
+	bracketleft_char_entry,		/*  6 */
+	bracketright_char_entry,	/*  7 */
+	colon_char_entry,		/*  8 */
+	dollar_char_entry,		/*  9 */
+	doublequote_char_entry,		/* 10 */
+	equal_char_entry,		/* 11 */
+	exclam_char_entry,		/* 12 */
+	greater_char_entry,		/* 13 */
+	hat_char_entry,			/* 14 */
+	hyphen_char_entry,		/* 15 */
+	less_char_entry,		/* 16 */
+	newline_char_entry,		/* 17 */
+	numbersign_char_entry,		/* 18 */
+	parenleft_char_entry,		/* 19 */
+	parenright_char_entry,		/* 20 */
+	percent_char_entry,		/* 21 */
+	plus_char_entry,		/* 22 */
+	question_char_entry,		/* 23 */
+	quote_char_entry,		/* 24 */
+	semicolon_char_entry,		/* 25 */
+#ifdef SGE_SUPPORT
+	space_char_entry,		/* 26 */
+	tab_char_entry,			/* 27 */
+	no_semantics_entry		/* 28 */
+#else
+	no_semantics_entry		/* 26 */
+#endif /* SGE_SUPPORT */
+};
+
+/*
+ * CHAR_SEMANTICS_ENTRIES should be the number of entries above.
+ * The last entry in char_semantics[] should be blank.
+ */
+#ifdef SGE_SUPPORT
+#define CHAR_SEMANTICS_ENTRIES	29
+/*
+#define CHAR_SEMANTICS_STRING	"&*@`\\|[]:$=!>-\n#()%+?;^<'\" \t"
+ */
+#else
+#define CHAR_SEMANTICS_ENTRIES	27
+/*
+#define CHAR_SEMANTICS_STRING	"&*@`\\|[]:$=!>-\n#()%+?;^<'\""
+ */
+#endif /* SGE_SUPPORT */
+
+/*
+ * Some utility macros
+ */
+#define ALLOC(x)		((struct _##x *)getmem(sizeof (struct _##x)))
+#define ALLOC_WC(x)		((wchar_t *)getmem((x) * SIZEOFWCHAR_T))
+#define FIND_LENGTH		-1
+#define GETNAME(a,b)		getname_fn((a), (b), false)
+#define IS_EQUAL(a,b)		(!strcmp((a), (b)))
+#define IS_EQUALN(a,b,n)	(!strncmp((a), (b), (n)))
+#define IS_WEQUAL(a,b)		(!wscmp((a), (b)))
+#define IS_WEQUALN(a,b,n)	(!wsncmp((a), (b), (n)))
+#define MBLEN(a)		mblen((a), MB_LEN_MAX)
+#define MBSTOWCS(a,b)		(void) mbstowcs_with_check((a), (b), MAXPATHLEN)
+#define	MBTOWC(a,b)		mbtowc((a), (b), MB_LEN_MAX)
+#define	SIZEOFWCHAR_T		(sizeof (wchar_t))
+#define VSIZEOF(v)		(sizeof (v) / sizeof ((v)[0]))
+#define WCSTOMBS(a,b)		(void) wcstombs((a), (b), (MAXPATHLEN * MB_LEN_MAX))
+#define WCTOMB(a,b)		(void) wctomb((a), (b))
+#define	HASH(v, c)		(v = (v)*31 + (unsigned int)(c))
+
+extern void mbstowcs_with_check(wchar_t *pwcs, const char *s, size_t n);
+
+/*
+ * Bits stored in funny vector to classify chars
+ */
+enum {
+	dollar_sem =		0001,
+	meta_sem =		0002,
+	percent_sem =		0004,
+	wildcard_sem =		0010,
+	command_prefix_sem =	0020,
+	special_macro_sem =	0040,
+	colon_sem =		0100,
+	parenleft_sem =		0200
+};
+
+/*
+ * Type returned from doname class functions
+ */
+typedef enum {
+	build_dont_know = 0,
+	build_failed,
+	build_ok,
+	build_in_progress,
+	build_running,		/* PARALLEL & DISTRIBUTED */
+	build_pending,		/* PARALLEL & DISTRIBUTED */
+	build_serial,		/* PARALLEL & DISTRIBUTED */
+	build_subtree		/* PARALLEL & DISTRIBUTED */
+} Doname;
+
+/*
+ * The String struct defines a string with the following layout
+ *	"xxxxxxxxxxxxxxxCxxxxxxxxxxxxxxx________"
+ *	^		^		^		^
+ *	|		|		|		|
+ *	buffer.start	text.p		text.end	buffer.end
+ *	text.p points to the next char to read/write.
+ */
+struct _String {
+	struct Text {
+		wchar_t		*p;	/* Read/Write pointer */
+		wchar_t		*end;	/* Read limit pointer */
+	}		text;
+	struct Physical_buffer {
+		wchar_t		*start;	/* Points to start of buffer */
+		wchar_t		*end;	/* End of physical buffer */
+	}		buffer;
+	Boolean		free_after_use:1;
+};
+
+#define STRING_BUFFER_LENGTH	1024
+#define INIT_STRING_FROM_STACK(str, buf) { \
+			str.buffer.start = (buf); \
+			str.text.p = (buf); \
+			str.text.end = NULL; \
+			str.buffer.end = (buf) \
+                          + (sizeof (buf)/SIZEOFWCHAR_T); \
+			str.free_after_use = false; \
+		  }
+
+#define APPEND_NAME(np, dest, len)	append_string((np)->string_mb, (dest), (len));
+
+class Wstring {
+	public:
+		struct _String	string;
+		wchar_t		string_buf[STRING_BUFFER_LENGTH];
+
+	public:
+		Wstring();
+		Wstring(struct _Name * name);
+		~Wstring();
+
+		void init(struct _Name * name);
+		void init(wchar_t * name, unsigned length);
+		unsigned length() {
+			return wslen(string.buffer.start);
+		};
+		void append_to_str(struct _String * str, unsigned off, unsigned length);
+
+		wchar_t * get_string() {
+			return string.buffer.start;
+		};
+
+		wchar_t * get_string(unsigned off) {
+			return string.buffer.start + off;
+		};
+
+		Boolean equaln(wchar_t * str, unsigned length);
+		Boolean equal(wchar_t * str);
+		Boolean equal(wchar_t * str, unsigned off);
+		Boolean equal(wchar_t * str, unsigned off, unsigned length);
+
+		Boolean equaln(Wstring * str, unsigned length);
+		Boolean equal(Wstring * str);
+		Boolean equal(Wstring * str, unsigned off);
+		Boolean equal(Wstring * str, unsigned off, unsigned length);
+};
+
+
+/*
+ * Used for storing the $? list and also for the "target + target:"
+ * construct.
+ */
+struct _Chain {
+	struct _Chain		*next;
+	struct _Name		*name;
+	struct _Percent	*percent_member;
+};
+
+/*
+ * Stores one command line for a rule
+ */
+struct _Cmd_line {
+	struct _Cmd_line	*next;
+	struct _Name		*command_line;
+	Boolean			make_refd:1;	/* $(MAKE) referenced? */
+	/*
+	 * Remember any command line prefixes given
+	 */
+	Boolean			ignore_command_dependency:1;	/* `?' */
+	Boolean			assign:1;			/* `=' */
+	Boolean			ignore_error:1;			/* `-' */
+	Boolean			silent:1;			/* `@' */
+	Boolean			always_exec:1;			/* `+' */
+};
+
+/*
+ * Linked list of targets/files
+ */
+struct _Dependency {
+	struct _Dependency	*next;
+	struct _Name		*name;
+	Boolean			automatic:1;
+	Boolean			stale:1;
+	Boolean			built:1;
+};
+
+/*
+ * The specials are markers for targets that the reader should special case
+ */
+typedef enum {
+	no_special,
+	built_last_make_run_special,
+	default_special,
+#ifdef NSE
+	derived_src_special,
+#endif
+	get_posix_special,
+	get_special,
+	ignore_special,
+	keep_state_file_special,
+	keep_state_special,
+	make_version_special,
+	no_parallel_special,
+	parallel_special,
+	posix_special,
+	precious_special,
+	sccs_get_posix_special,
+	sccs_get_special,
+	silent_special,
+	suffixes_special,
+	svr4_special,
+	localhost_special
+} Special;
+
+typedef enum {
+	no_colon,
+	one_colon,
+	two_colon,
+	equal_seen,
+	conditional_seen,
+	none_seen
+} Separator;
+
+/*
+ * Magic values for the timestamp stored with each name object
+ */
+
+#if defined (linux)
+typedef struct timespec timestruc_t;
+#endif
+
+extern const timestruc_t file_no_time;
+extern const timestruc_t file_doesnt_exist;
+extern const timestruc_t file_is_dir;
+extern const timestruc_t file_min_time;
+extern const timestruc_t file_max_time;
+
+/*
+ * Each Name has a list of properties
+ * The properties are used to store information that only
+ * a subset of the Names need
+ */
+typedef enum {
+	no_prop,
+	conditional_prop,
+	line_prop,
+	macro_prop,
+	makefile_prop,
+	member_prop,
+	recursive_prop,
+	sccs_prop,
+	suffix_prop,
+	target_prop,
+	time_prop,
+	vpath_alias_prop,
+	long_member_name_prop,
+	macro_append_prop,
+	env_mem_prop
+} Property_id;
+
+typedef enum {
+	no_daemon = 0,
+	chain_daemon
+} Daemon;
+
+struct _Env_mem {
+	char		*value;
+};
+
+struct _Macro_appendix {
+	struct _Name		*value;
+	struct _Name		*value_to_append;
+};
+
+struct _Macro {
+	/*
+	* For "ABC = xyz" constructs
+	* Name "ABC" get one macro prop
+	*/
+	struct _Name		*value;
+#ifdef NSE
+	Boolean                 imported:1;
+#endif
+	Boolean			exported:1;
+	Boolean			read_only:1;
+	/*
+	* This macro is defined conditionally
+	*/
+	Boolean			is_conditional:1;
+	/*
+	* The list for $? is stored as a structured list that
+	* is translated into a string iff it is referenced.
+	* This is why  some macro values need a daemon. 
+	*/
+#if defined(HP_UX) || defined(linux)
+	Daemon			daemon;
+#else
+	Daemon			daemon:2;
+#endif
+};
+
+struct _Macro_list {
+	struct _Macro_list	*next;
+	char			*macro_name; 
+	char			*value; 
+};
+
+enum sccs_stat {
+	DONT_KNOW_SCCS = 0,
+	NO_SCCS,
+	HAS_SCCS
+};
+
+struct _Name {
+	struct _Property	*prop;		/* List of properties */
+	char			*string_mb;     /* Multi-byte name string */
+	struct {
+		unsigned int		length;
+	}                       hash;
+	struct {
+		timestruc_t		time;		/* Modification */
+		int			stat_errno;	/* error from "stat" */
+		off_t			size;		/* Of file */
+		mode_t			mode;		/* Of file */
+#if defined(HP_UX) || defined(linux)
+		Boolean			is_file;
+		Boolean			is_dir;
+		Boolean			is_sym_link;
+		Boolean			is_precious;
+		enum sccs_stat		has_sccs;
+#else
+		Boolean			is_file:1;
+		Boolean			is_dir:1;
+		Boolean			is_sym_link:1;
+		Boolean			is_precious:1;
+#ifdef NSE
+                Boolean                 is_derived_src:1;
+#endif
+		enum sccs_stat		has_sccs:2;
+#endif
+	}                       stat;
+	/*
+	 * Count instances of :: definitions for this target
+	 */
+	short			colon_splits;
+	/*
+	 * We only clear the automatic depes once per target per report
+	 */
+	short			temp_file_number;
+	/*
+	 * Count how many conditional macros this target has defined
+	 */
+	short			conditional_cnt;
+	/*
+	 * A conditional macro was used when building this target
+	 */
+	Boolean			depends_on_conditional:1;
+	/* 
+	 * Pointer to list of conditional macros which were used to build 
+	 * this target
+	 */
+	struct _Macro_list	*conditional_macro_list;
+	Boolean			has_member_depe:1;
+	Boolean			is_member:1;
+	/*
+	 * This target is a directory that has been read
+	 */
+	Boolean			has_read_dir:1;
+	/*
+	 * This name is a macro that is now being expanded
+	 */
+	Boolean			being_expanded:1;
+	/*
+	 * This name is a magic name that the reader must know about
+	 */
+#if defined(HP_UX) || defined(linux)
+	Special			special_reader;
+	Doname			state;
+	Separator		colons;
+#else
+	Special			special_reader:5;
+	Doname			state:3;
+	Separator		colons:3;
+#endif
+	Boolean			has_depe_list_expanded:1;
+	Boolean			suffix_scan_done:1;
+	Boolean			has_complained:1;	/* For sccs */
+	/*
+	 * This target has been built during this make run
+	 */
+	Boolean			ran_command:1;
+	Boolean			with_squiggle:1;	/* for .SUFFIXES */
+	Boolean			without_squiggle:1;	/* for .SUFFIXES */
+	Boolean			has_read_suffixes:1;	/* Suffix list cached*/
+	Boolean			has_suffixes:1;
+	Boolean			has_target_prop:1;
+	Boolean			has_vpath_alias_prop:1;
+	Boolean			dependency_printed:1;	/* For dump_make_state() */
+	Boolean			dollar:1;		/* In namestring */
+	Boolean			meta:1;			/* In namestring */
+	Boolean			percent:1;		/* In namestring */
+	Boolean			wildcard:1;		/* In namestring */
+        Boolean                 has_parent:1;
+        Boolean                 is_target:1;
+	Boolean			has_built:1;
+	Boolean			colon:1;		/* In namestring */
+	Boolean			parenleft:1;		/* In namestring */
+	Boolean			has_recursive_dependency:1;
+	Boolean			has_regular_dependency:1;
+	Boolean			is_double_colon:1;
+	Boolean			is_double_colon_parent:1;
+	Boolean			has_long_member_name:1;
+	/*
+	 * allowed to run in parallel
+	 */
+	Boolean			parallel:1;
+	/*
+	 * not allowed to run in parallel
+	 */
+	Boolean			no_parallel:1;
+	/*
+	 * used in dependency_conflict
+	 */
+	Boolean			checking_subtree:1;
+	Boolean			added_pattern_conditionals:1;
+	/*
+	 * rechecking target for possible rebuild
+	 */
+	Boolean			rechecking_target:1;
+	/*
+	 * build this target in silent mode
+	 */
+	Boolean			silent_mode:1;
+	/*
+	 * build this target in ignore error mode
+	 */
+	Boolean			ignore_error_mode:1;
+	Boolean			dont_activate_cond_values:1;
+	/*
+	 * allowed to run serially on local host
+	 */
+	Boolean			localhost:1;
+};
+
+/*
+ * Stores the % matched default rules
+ */
+struct _Percent {
+	struct _Percent	*next;
+	struct _Name		**patterns;
+	struct _Name		*name;
+	struct _Percent		*dependencies;
+	struct _Cmd_line	*command_template;
+	struct _Chain		*target_group;
+	int			patterns_total;
+	Boolean			being_expanded;
+};
+
+struct Conditional {
+	/*
+	 * For "foo := ABC [+]= xyz" constructs
+	 * Name "foo" gets one conditional prop
+	 */
+	struct _Name		*target;
+	struct _Name		*name;
+	struct _Name		*value;
+	int			sequence;
+	Boolean			append:1;
+};
+
+struct Line {
+	/*
+	 * For "target : dependencies" constructs
+	 * Name "target" gets one line prop
+	 */
+	struct _Cmd_line	*command_template;
+	struct _Cmd_line	*command_used;
+	struct _Dependency	*dependencies;
+	timestruc_t		dependency_time;
+	struct _Chain		*target_group;
+	Boolean			is_out_of_date:1;
+	Boolean			sccs_command:1;
+	Boolean			command_template_redefined:1;
+	Boolean			dont_rebuild_command_used:1;
+	/*
+	 * Values for the dynamic macros
+	 */
+	struct _Name		*target;
+	struct _Name		*star;
+	struct _Name		*less;
+	struct _Name		*percent;
+	struct _Chain		*query;
+};
+
+struct Makefile {
+	/*
+	 * Names that reference makefiles gets one prop
+	 */
+	wchar_t			*contents;
+	off_t			size;
+};
+
+struct Member {
+	/*
+	 * For "lib(member)" and "lib((entry))" constructs
+	 * Name "lib(member)" gets one member prop
+	 * Name "lib((entry))" gets one member prop
+	 * The member field is filled in when the prop is refd
+	 */
+	struct _Name		*library;
+	struct _Name		*entry;
+	struct _Name		*member;
+};
+
+struct Recursive {
+	/*
+	 * For "target: .RECURSIVE dir makefiles" constructs
+	 * Used to keep track of recursive calls to make
+	 * Name "target" gets one recursive prop
+	 */
+	struct _Name		*directory;
+	struct _Name		*target;
+	struct _Dependency	*makefiles;
+	Boolean			has_built;
+	Boolean			in_depinfo;
+};
+
+struct Sccs {
+	/*
+	 * Each file that has a SCCS s. file gets one prop
+	 */
+	struct _Name		*file;
+};
+
+struct Suffix {
+	/*
+	 * Cached list of suffixes that can build this target
+	 * suffix is built from .SUFFIXES
+	 */
+	struct _Name		*suffix;
+	struct _Cmd_line	*command_template;
+};
+
+struct Target {
+	/*
+	 * For "target:: dependencies" constructs
+	 * The "::" construct is handled by converting it to
+	 * "foo: 1@foo" + "1@foo: dependecies"
+	 * "1@foo" gets one target prop
+	 * This target prop cause $@ to be bound to "foo"
+	 * not "1@foo" when the rule is evaluated
+	 */
+	struct _Name		*target;
+};
+
+struct STime {
+	/*
+	 * Save the original time for :: targets
+	 */
+	timestruc_t			time;
+};
+
+struct Vpath_alias {
+	/*
+	 * If a file was found using the VPATH it gets
+	 * a vpath_alias prop
+	 */
+	struct _Name		*alias;
+};
+
+struct Long_member_name {
+	/*
+	 * Targets with a truncated member name carries
+	 * the full lib(member) name for the state file
+	 */
+	struct _Name		*member_name;
+};
+
+union Body {
+	struct _Macro		macro;
+	struct Conditional	conditional;
+	struct Line		line;
+	struct Makefile		makefile;
+	struct Member		member;
+	struct Recursive	recursive;
+	struct Sccs		sccs;
+	struct Suffix		suffix;
+	struct Target		target;
+	struct STime		time;
+	struct Vpath_alias	vpath_alias;
+	struct Long_member_name	long_member_name;
+	struct _Macro_appendix	macro_appendix;
+	struct _Env_mem		env_mem;
+};
+
+#define PROPERTY_HEAD_SIZE (sizeof (struct _Property)-sizeof (union Body))
+struct _Property {
+	struct _Property	*next;
+#if defined(HP_UX) || defined(linux)
+	Property_id		type;
+#else
+	Property_id		type:4;
+#endif
+	union Body		body;
+};
+
+/* Structure for dynamic "ascii" arrays */ 
+struct ASCII_Dyn_Array {
+	char			*start;
+	size_t			size;
+};
+
+struct _Envvar {
+	struct _Name		*name;
+	struct _Name		*value;
+	struct _Envvar		*next;
+	char			*env_string;
+	Boolean			already_put:1;
+};
+
+/*
+ * Macros for the reader
+ */
+#define GOTO_STATE(new_state) { \
+				  SET_STATE(new_state); \
+				    goto enter_state; \
+			      }
+#define SET_STATE(new_state) state = (new_state)
+
+#define UNCACHE_SOURCE()	if (source != NULL) { \
+					source->string.text.p = source_p; \
+				  }
+#define CACHE_SOURCE(comp)	if (source != NULL) { \
+					source_p = source->string.text.p - \
+					  (comp); \
+					source_end = source->string.text.end; \
+				  }
+#define GET_NEXT_BLOCK_NOCHK(source)	{ UNCACHE_SOURCE(); \
+				 source = get_next_block_fn(source); \
+				 CACHE_SOURCE(0) \
+			   }
+#define GET_NEXT_BLOCK(source)	{ GET_NEXT_BLOCK_NOCHK(source); \
+				 if (source != NULL && source->error_converting) { \
+				 	GOTO_STATE(illegal_bytes_state); \
+				 } \
+			   }
+#define GET_CHAR()		((source == NULL) || \
+				(source_p >= source_end) ? 0 : *source_p)
+
+struct _Source {
+	struct _String		string;
+	struct _Source		*previous;
+	off_t			bytes_left_in_file;
+	short			fd;
+	Boolean			already_expanded:1;
+	Boolean			error_converting:1;
+	char			*inp_buf;
+	char			*inp_buf_end;
+	char			*inp_buf_ptr;
+};
+
+typedef enum {
+	reading_nothing,
+	reading_makefile,
+	reading_statefile,
+	rereading_statefile,
+	reading_cpp_file
+} Makefile_type;
+
+/*
+ * Typedefs for all structs
+ */
+typedef struct _Chain		*Chain, Chain_rec;
+typedef struct _Envvar		*Envvar, Envvar_rec;
+typedef struct _Macro_list	*Macro_list, Macro_list_rec;
+typedef struct _Name		*Name, Name_rec;
+typedef struct _Property	*Property, Property_rec;
+typedef struct _Source		*Source, Source_rec;
+typedef struct _String		*String, String_rec;
+
+/*
+ * name records hash table.
+ */
+struct Name_set {
+private:
+	// single node in a tree
+	struct entry {
+		entry(Name name_, entry *parent_) : 
+			name(name_),
+			parent(parent_),
+			left(0),
+			right(0),
+			depth(1)
+		{}
+
+		Name		name;
+
+		entry		*parent;
+		entry		*left;
+		entry		*right;
+		unsigned	depth;
+
+		void setup_depth() {
+			unsigned rdepth = (right != 0) ? right->depth : 0;
+			unsigned ldepth = (left != 0) ? left->depth : 0;
+			depth = 1 + ((ldepth > rdepth) ? ldepth : rdepth);
+		}
+	};
+
+public:
+	// make iterator a friend of Name_set to have access to struct entry
+	struct iterator;
+	friend struct Name_set::iterator;
+
+	// iterator over tree nodes
+	struct iterator {
+	public:
+		// constructors
+		iterator() : node(0) {}
+		iterator(entry *node_) : node(node_) {}
+
+		// dereference operator
+		Name operator->() const { return node->name; }
+
+		// conversion operator
+		operator Name() { return node->name; }
+
+		// assignment operator
+		iterator& operator=(const iterator &o) { node = o.node; return *this; }
+
+		// equality/inequality operators
+		int operator==(const iterator &o) const { return (node == o.node); }
+		int operator!=(const iterator &o) const { return (node != o.node); }
+
+		// pre/post increment operators
+		iterator& operator++();
+		iterator  operator++(int) { iterator it = *this; ++*this; return it; }
+
+	private:
+		// the node iterator points to
+		entry *node;
+	};
+
+public:
+	// constructor
+	Name_set() : root(0) {}
+
+	// lookup, insert and remove operations
+	Name lookup(const char *key);
+	Name insert(const char *key, Boolean &found);
+	void insert(Name name);
+
+	// begin/end iterators
+	iterator begin() const;
+	iterator end() const { return iterator(); }
+
+private:
+	// rebalance given node
+	void	rebalance(entry *node);
+
+private:
+	// tree root
+	entry	*root;
+};
+
+/*
+ *	extern declarations for all global variables.
+ *	The actual declarations are in globals.cc
+ */
+extern char		char_semantics[];
+extern wchar_t		char_semantics_char[];
+extern Macro_list	cond_macro_list;
+extern Boolean		conditional_macro_used;
+extern Boolean		do_not_exec_rule;		/* `-n' */
+extern Boolean		dollarget_seen;
+extern Boolean		dollarless_flag;
+extern Name		dollarless_value;
+extern char		**environ;
+extern Envvar		envvar;
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+extern int		exit_status;
+#endif
+extern wchar_t		*file_being_read;
+/* Variable gnu_style=true if env. var. SUN_MAKE_COMPAT_MODE=GNU (RFE 4866328) */
+extern Boolean		gnu_style;
+extern Name_set		hashtab;
+extern Name		host_arch;
+extern Name		host_mach;
+extern int		line_number;
+extern char		*make_state_lockfile;
+extern Boolean		make_word_mentioned;
+extern Makefile_type	makefile_type;
+extern char		mbs_buffer[];
+extern Name		path_name;
+extern Boolean		posix;
+extern Name		query;
+extern Boolean		query_mentioned;
+extern Name		hat;
+extern Boolean		reading_environment;
+extern Name		shell_name;
+extern Boolean		svr4;
+extern Name		target_arch;
+extern Name		target_mach;
+extern Boolean		tilde_rule;
+extern wchar_t		wcs_buffer[];
+extern Boolean		working_on_targets;
+extern Name		virtual_root;
+extern Boolean		vpath_defined;
+extern Name		vpath_name;
+extern Boolean		make_state_locked;
+#if defined (TEAMWARE_MAKE_CMN) && defined(REDIRECT_ERR)
+extern Boolean		out_err_same;
+#endif
+extern pid_t		childPid;
+extern nl_catd		libmksh_catd;
+
+/*
+ * RFE 1257407: make does not use fine granularity time info available from stat.
+ * High resolution time comparison.
+ */
+
+inline int
+operator==(const timestruc_t &t1, const timestruc_t &t2) {
+	return ((t1.tv_sec == t2.tv_sec) && (t1.tv_nsec == t2.tv_nsec));
+}
+
+inline int
+operator!=(const timestruc_t &t1, const timestruc_t &t2) {
+	return ((t1.tv_sec != t2.tv_sec) || (t1.tv_nsec != t2.tv_nsec));
+}
+
+inline int
+operator>(const timestruc_t &t1, const timestruc_t &t2) {
+	if (t1.tv_sec == t2.tv_sec) {
+		return (t1.tv_nsec > t2.tv_nsec);
+	}
+	return (t1.tv_sec > t2.tv_sec);
+}
+
+inline int
+operator>=(const timestruc_t &t1, const timestruc_t &t2) {
+	if (t1.tv_sec == t2.tv_sec) {
+		return (t1.tv_nsec >= t2.tv_nsec);
+	}
+	return (t1.tv_sec > t2.tv_sec);
+}
+
+inline int
+operator<(const timestruc_t &t1, const timestruc_t &t2) {
+	if (t1.tv_sec == t2.tv_sec) {
+		return (t1.tv_nsec < t2.tv_nsec);
+	}
+	return (t1.tv_sec < t2.tv_sec);
+}
+
+inline int
+operator<=(const timestruc_t &t1, const timestruc_t &t2) {
+	if (t1.tv_sec == t2.tv_sec) {
+		return (t1.tv_nsec <= t2.tv_nsec);
+	}
+	return (t1.tv_sec < t2.tv_sec);
+}
+
+#endif
--- /dev/null	2015-05-20 11:04:14.000000000 -0400
+++ new/usr/src/cmd/make/include/mksh/dosys.h	2015-05-20 11:04:14.855457385 -0400
@@ -0,0 +1,50 @@
+#ifndef _MKSH_DOSYS_H
+#define _MKSH_DOSYS_H
+/*
+ * 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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)dosys.h 1.9 06/12/12
+ */
+
+#pragma	ident	"@(#)dosys.h	1.9	06/12/12"
+
+#include <mksh/defs.h>
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+#	include <rw/xdrstrea.h>
+#endif
+#include <vroot/vroot.h>
+
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+extern Boolean	await(register Boolean ignore_error, register Boolean silent_error, Name target, wchar_t *command, pid_t running_pid, Boolean send_mtool_msgs, XDR *xdrs, int job_msg_id);
+#else
+extern Boolean	await(register Boolean ignore_error, register Boolean silent_error, Name target, wchar_t *command, pid_t running_pid, Boolean send_mtool_msgs, void *xdrs, int job_msg_id);
+#endif
+extern int	doexec(register wchar_t *command, register Boolean ignore_error, Boolean redirect_out_err, char *stdout_file, char *stderr_file, pathpt vroot_path, int nice_prio);
+extern int	doshell(wchar_t *command, register Boolean ignore_error, Boolean redirect_out_err, char *stdout_file, char *stderr_file, int nice_prio);
+extern Doname	dosys_mksh(register Name command, register Boolean ignore_error, register Boolean call_make, Boolean silent_error, Boolean always_exec, Name target, Boolean redirect_out_err, char *stdout_file, char *stderr_file, pathpt vroot_path, int nice_prio);
+extern void	redirect_io(char *stdout_file, char *stderr_file);
+extern void	sh_command2string(register String command, register String destination);
+
+#endif
--- /dev/null	2015-05-20 11:04:15.000000000 -0400
+++ new/usr/src/cmd/make/include/mksh/globals.h	2015-05-20 11:04:15.045727895 -0400
@@ -0,0 +1,35 @@
+#ifndef _MKSH_GLOBALS_H
+#define _MKSH_GLOBALS_H
+/*
+ * 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 1994 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)globals.h 1.2 06/12/12
+ */
+
+#pragma	ident	"@(#)globals.h	1.2	06/12/12"
+
+#include <mksh/defs.h>
+
+#endif
--- /dev/null	2015-05-20 11:04:15.000000000 -0400
+++ new/usr/src/cmd/make/include/mksh/i18n.h	2015-05-20 11:04:15.239347949 -0400
@@ -0,0 +1,38 @@
+#ifndef _MKSH_I18N_H
+#define _MKSH_I18N_H
+/*
+ * 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 1994 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)i18n.h 1.2 06/12/12
+ */
+
+#pragma	ident	"@(#)i18n.h	1.2	06/12/12"
+
+#include <mksh/defs.h>
+
+extern int	get_char_semantics_entry(wchar_t ch);
+extern char	get_char_semantics_value(wchar_t ch);
+
+#endif
--- /dev/null	2015-05-20 11:04:15.000000000 -0400
+++ new/usr/src/cmd/make/include/mksh/libmksh_init.h	2015-05-20 11:04:15.428164746 -0400
@@ -0,0 +1,36 @@
+#ifndef _MKSH_INIT_H
+#define _MKSH_INIT_H
+/*
+ * 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 1995 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)libmksh_init.h 1.2 06/12/12
+ */
+
+#pragma	ident	"@(#)libmksh_init.h	1.2	06/12/12"
+
+int libmksh_init()
+void libmksh_fini();
+
+#endif
--- /dev/null	2015-05-20 11:04:15.000000000 -0400
+++ new/usr/src/cmd/make/include/mksh/macro.h	2015-05-20 11:04:15.615253216 -0400
@@ -0,0 +1,41 @@
+#ifndef _MKSH_MACRO_H
+#define _MKSH_MACRO_H
+/*
+ * 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 2002 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)macro.h 1.3 06/12/12
+ */
+
+#pragma	ident	"@(#)macro.h	1.3	06/12/12"
+
+#include <mksh/defs.h>
+
+extern void	expand_macro(register Source source, register String destination, wchar_t *current_string, Boolean cmd);
+extern void	expand_value(Name value, register String destination, Boolean cmd);
+extern Name	getvar(register Name name);
+
+extern Property	setvar_daemon(register Name name, register Name value, Boolean append, Daemon daemon, Boolean strip_trailing_spaces, short debug_level);
+
+#endif
--- /dev/null	2015-05-20 11:04:15.000000000 -0400
+++ new/usr/src/cmd/make/include/mksh/misc.h	2015-05-20 11:04:15.804921914 -0400
@@ -0,0 +1,60 @@
+#ifndef _MKSH_MISC_H
+#define _MKSH_MISC_H
+/*
+ * 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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)misc.h 1.4 06/12/12
+ */
+
+#pragma	ident	"@(#)misc.h	1.4	06/12/12"
+
+#include <mksh/defs.h>
+
+extern void	append_char(wchar_t from, register String to);
+extern Property	append_prop(register Name target, register Property_id type);
+extern void	append_string(register wchar_t *from, register String to, register int length);
+extern void	enable_interrupt(register void (*handler) (int));
+extern char	*errmsg(int errnum);
+extern void	fatal_mksh(char * message, ...);
+extern void	fatal_reader_mksh(char * pattern, ...);
+extern char	*get_current_path_mksh(void);
+extern Property	get_prop(register Property start, register Property_id type);
+extern char	*getmem(register int size);
+extern Name	getname_fn(wchar_t *name, register int len, register Boolean dont_enter, register Boolean * foundp = NULL);
+extern void	store_name(Name name);
+extern void	free_name(Name name);
+extern void	handle_interrupt_mksh(int);
+extern Property	maybe_append_prop(register Name target, register Property_id type);
+extern void	retmem(wchar_t *p);
+extern void	retmem_mb(caddr_t p);
+extern void	setup_char_semantics(void);
+extern void	setup_interrupt(register void (*handler) (int));
+extern void	warning_mksh(char * message, ...);
+
+extern void	append_string(register char *from, register String to, register int length);
+extern wchar_t	*get_wstring(char * from);
+
+
+#endif
--- /dev/null	2015-05-20 11:04:16.000000000 -0400
+++ new/usr/src/cmd/make/include/mksh/mksh.h	2015-05-20 11:04:15.993274410 -0400
@@ -0,0 +1,49 @@
+#ifndef _MKSH_MKSH_H
+#define _MKSH_MKSH_H
+/*
+ * 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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)mksh.h 1.7 06/12/12
+ */
+
+#pragma	ident	"@(#)mksh.h	1.7	06/12/12"
+
+/*
+ * Included files
+ */
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+#	include <dm/Avo_DmakeCommand.h>
+#endif
+
+#include <mksh/defs.h>
+#include <unistd.h>
+
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+
+extern int	do_job(Avo_DmakeCommand *cmd_list[], char *env_list[], char *stdout_file, char *stderr_file, char *cwd, char *cnwd, int ignore, int silent, pathpt vroot_path, char *shell, int nice_prio);
+
+#endif /* TEAMWARE_MAKE_CMN */
+
+#endif
--- /dev/null	2015-05-20 11:04:16.000000000 -0400
+++ new/usr/src/cmd/make/include/mksh/read.h	2015-05-20 11:04:16.200362566 -0400
@@ -0,0 +1,37 @@
+#ifndef _MKSH_READ_H
+#define _MKSH_READ_H
+/*
+ * 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 1994 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)read.h 1.2 06/12/12
+ */
+
+#pragma	ident	"@(#)read.h	1.2	06/12/12"
+
+#include <mksh/defs.h>
+
+extern Source	get_next_block_fn(register Source source);
+
+#endif
--- /dev/null	2015-05-20 11:04:16.000000000 -0400
+++ new/usr/src/cmd/make/include/vroot/args.h	2015-05-20 11:04:16.392636120 -0400
@@ -0,0 +1,70 @@
+/*
+ * 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 1999 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)args.h 1.7 06/12/12
+ */
+
+#pragma	ident	"@(#)args.h	1.7	06/12/12"
+
+#ifndef _ARGS_H_
+#define _ARGS_H_
+
+#include <sys/syscall.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/param.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+
+typedef enum { rw_read, rw_write} rwt, *rwpt;
+
+extern	void	translate_with_thunk(register char *filename, int (*thunk) (char *), pathpt path_vector, pathpt vroot_vector, rwt rw);
+
+union Args {
+	struct { int mode;} access;
+	struct { int mode;} chmod;
+	struct { int user; int group;} chown;
+	struct { int mode;} creat;
+	struct { char **argv; char **environ;} execve;
+	struct { struct stat *buffer;} lstat;
+	struct { int mode;} mkdir;
+	struct { char *name; int mode;} mount;
+	struct { int flags; int mode;} open;
+	struct { char *buffer; int buffer_size;} readlink;
+	struct { struct stat *buffer;} stat;
+#ifndef SUN5_0
+	struct { struct statfs *buffer;} statfs;
+#endif
+	struct { int length;} truncate;
+	struct { struct timeval *time;} utimes;
+};
+
+extern	union Args	vroot_args;
+extern	int		vroot_result;
+
+#endif
--- /dev/null	2015-05-20 11:04:16.000000000 -0400
+++ new/usr/src/cmd/make/include/vroot/report.h	2015-05-20 11:04:16.581379650 -0400
@@ -0,0 +1,59 @@
+/*
+ * 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 1994 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)report.h 1.6 06/12/12
+ */
+
+#pragma	ident	"@(#)report.h	1.6	06/12/12"
+
+#ifndef _REPORT_H_
+#define _REPORT_H_
+
+#include <stdio.h>
+
+extern FILE	*get_report_file(void);
+extern char	*get_target_being_reported_for(void);
+extern void	report_dependency(register char *name);
+extern int	file_lock(char *name, char *lockname, int *file_locked, int timeout);
+#ifdef NSE
+extern char	*setenv(char *name, char *value);
+#endif
+
+#define SUNPRO_DEPENDENCIES "SUNPRO_DEPENDENCIES"
+#define LD 	"LD"
+#define COMP 	"COMP"
+
+/* the following definitions define the interface between make and
+ * NSE - the two systems must track each other.
+ */
+#define NSE_DEPINFO 		".nse_depinfo"
+#define NSE_DEPINFO_LOCK 	".nse_depinfo.lock"
+#define NSE_DEP_ENV 		"NSE_DEP"
+#define NSE_TFS_PUSH 		"/usr/nse/bin/tfs_push"
+#define NSE_TFS_PUSH_LEN 	8
+#define NSE_VARIANT_ENV 	"NSE_VARIANT"
+#define NSE_RT_SOURCE_NAME 	"Shared_Source"
+
+#endif
--- /dev/null	2015-05-20 11:04:16.000000000 -0400
+++ new/usr/src/cmd/make/include/vroot/vroot.h	2015-05-20 11:04:16.770078403 -0400
@@ -0,0 +1,67 @@
+/*
+ * 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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)vroot.h 1.10 06/12/12
+ */
+
+#pragma	ident	"@(#)vroot.h	1.10	06/12/12"
+
+#ifndef _VROOT_H_
+#define _VROOT_H_
+
+#include <stdio.h>
+#include <nl_types.h>
+
+#define VROOT_DEFAULT ((pathpt)-1)
+
+typedef struct {
+	char		*path;
+	short		length;
+} pathcellt, *pathcellpt, patht;
+typedef patht		*pathpt;
+
+extern	void		add_dir_to_path(register char *path, register pathpt *pointer, register int position);
+extern	void		flush_path_cache(void);
+extern	void		flush_vroot_cache(void);
+extern	char		*get_path_name(void);
+extern	char		*get_vroot_path(register char **vroot, register char **path, register char **filename);
+extern	char		*get_vroot_name(void);
+extern	int		open_vroot(char *path, int flags, int mode, pathpt vroot_path, pathpt vroot_vroot);
+extern	pathpt		parse_path_string(register char *string, register int remove_slash);
+extern	void		scan_path_first(void);
+extern	void		scan_vroot_first(void);
+extern	void		set_path_style(int style);
+
+extern	int		access_vroot(char *path, int mode, pathpt vroot_path, pathpt vroot_vroot);
+
+extern	int		execve_vroot(char *path, char **argv, char **environ, pathpt vroot_path, pathpt vroot_vroot);
+
+extern	int		lstat_vroot(char *path, struct stat *buffer, pathpt vroot_path, pathpt vroot_vroot);
+extern	int		stat_vroot(char *path, struct stat *buffer, pathpt vroot_path, pathpt vroot_vroot);
+extern	int		readlink_vroot(char *path, char *buffer, int buffer_size, pathpt vroot_path, pathpt vroot_vroot);
+
+
+extern nl_catd	libvroot_catd;
+#endif
--- /dev/null	2015-05-20 11:04:16.000000000 -0400
+++ new/usr/src/cmd/make/lib/Lib.mk	2015-05-20 11:04:16.970089142 -0400
@@ -0,0 +1,67 @@
+#
+# 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 2001 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Lib.mk 1.13 06/12/12
+#
+
+# Definitions of the libraries supplied by make/dmake.
+# You must correctly define TOP before including this file!
+
+MAKE_TOP	= $(TOP)/Make
+
+LIBBSD_DIR	= $(MAKE_TOP)/lib/bsd
+LIBBSD		= $(LIBBSD_DIR)/$(VARIANT)/libbsd.a
+
+LIBDMRXM_DIR	= $(MAKE_TOP)/lib/dmrxm
+LIBDMRXM	= $(LIBDMRXM_DIR)/$(VARIANT)/libdmrxm.a
+
+LIBDMRXS_DIR	= $(MAKE_TOP)/lib/dmrxs
+LIBDMRXS	= $(LIBDMRXS_DIR)/$(VARIANT)/libdmrxs.a
+
+LIBMAKESTATE_DIR = $(MAKE_TOP)/lib/makestate
+LIBMAKESTATE	= $(LIBMAKESTATE_DIR)/$(VARIANT)/libmakestate.a
+
+LIBMKSDMSI18N_DIR = $(MAKE_TOP)/lib/mksdmsi18n
+LIBMKSDMSI18N	= $(LIBMKSDMSI18N_DIR)/$(VARIANT)/libmksdmsi18n.a
+
+LIBMKSH_DIR	= $(MAKE_TOP)/lib/mksh
+LIBMKSH		= $(LIBMKSH_DIR)/$(VARIANT)/libmksh.a
+
+LIBVROOT_DIR	= $(MAKE_TOP)/lib/vroot
+LIBVROOT	= $(LIBVROOT_DIR)/$(VARIANT)/libvroot.a
+
+LIBDM_DIR	= $(MAKE_TOP)/lib/dm
+LIBDM		= $(LIBDM_DIR)/$(VARIANT)/libdm.a
+
+LIBDMCONF_DIR	= $(MAKE_TOP)/lib/dmconf
+LIBDMCONF	= $(LIBDMCONF_DIR)/$(VARIANT)/libdmconf.a
+
+LIBDMRC_DIR	= $(MAKE_TOP)/lib/dmrc
+LIBDMRC		= $(LIBDMRC_DIR)/$(VARIANT)/libdmrc.a
+
+LIBDMTHREAD_DIR	= $(MAKE_TOP)/lib/dmthread
+LIBDMTHREAD	= $(LIBDMTHREAD_DIR)/$(VARIANT)/libdmthread.a
+
+LIBRX_DIR	= $(MAKE_TOP)/lib/rx
+LIBRX		= $(LIBRX_DIR)/$(VARIANT)/librx.a
+
--- /dev/null	2015-05-20 11:04:17.000000000 -0400
+++ new/usr/src/cmd/make/lib/Makefile	2015-05-20 11:04:17.446686033 -0400
@@ -0,0 +1,39 @@
+#
+# 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 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.8 06/12/12
+#
+# @(#)Makefile	1.4	96/03/16 SMI
+
+TOP =	../..
+
+SUBDIRS =	\
+		makestate \
+		bsd \
+		dmrxm \
+		dmrxs \
+		mksdmsi18n \
+		mksh \
+		vroot
+
+include $(TOP)/rules/recurse.mk
--- /dev/null	2015-05-20 11:04:17.000000000 -0400
+++ new/usr/src/cmd/make/lib/bsd/Makefile	2015-05-20 11:04:17.635342455 -0400
@@ -0,0 +1,29 @@
+#
+# 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 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.5 06/12/12
+#
+
+TOP =		../../..
+include $(TOP)/rules/variant.mk
+include $(TOP)/rules/derived.mk
--- /dev/null	2015-05-20 11:04:17.000000000 -0400
+++ new/usr/src/cmd/make/lib/bsd/src/Makefile	2015-05-20 11:04:17.824610768 -0400
@@ -0,0 +1,49 @@
+#
+# 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 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.3 06/12/12
+#
+
+# Generic makefile for use in src directories.  Knows how to make common things
+# in the right $(VARIANT) directory.
+
+include $(TOP)/rules/variant.mk
+
+all :=		TARG = all 
+install :=		TARG = install 
+clean :=		TARG = clean 
+test :=		TARG = test
+l10n_install :=	TARG = l10n_install
+i18n_install :=	TARG = i18n_install
+
+SRC =		../src
+MFLAGS += 	SRC=$(SRC)
+
+# See $(TOP)/rules/master.mk for how these are built.
+%.h %.cc %.C %.E %.o all install clean test l10n_install i18n_install: FRC
+	@ if [ ! -d ../$(VARIANT) ]; then \
+		mkdir ../$(VARIANT) ; \
+	fi
+	cd ../$(VARIANT); $(MAKE) $(MFLAGS) -f $(SRC)/Variant.mk DESTDIR=$(DESTDIR) $@
+
+FRC:
--- /dev/null	2015-05-20 11:04:18.000000000 -0400
+++ new/usr/src/cmd/make/lib/bsd/src/Variant.mk	2015-05-20 11:04:18.015814832 -0400
@@ -0,0 +1,45 @@
+#
+# 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 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Variant.mk 1.13 06/12/12
+#
+
+TOP =		 ../../../..
+include ${TOP}/rules/master.mk
+
+PKG_TOP =	 $(TOP)/Make
+CPPFLAGS +=	 -I${PKG_TOP}/include
+MSG_FILE = libbsd.msg
+I18N_DIRS = $(SRC)
+
+CCSRCS =		bsd.cc
+CSRCS =
+
+HDRS_DIR =	 ${PKG_TOP}/include/bsd
+
+.INIT: ${HDRS_DIR}/bsd.h
+
+LIBNAME =	 libbsd.a
+
+include ${TOP}/rules/lib.mk
+
--- /dev/null	2015-05-20 11:04:18.000000000 -0400
+++ new/usr/src/cmd/make/lib/bsd/src/bsd.cc	2015-05-20 11:04:18.217427786 -0400
@@ -0,0 +1,182 @@
+/*
+ * 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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)bsd.cc 1.6 06/12/12
+ */
+
+#pragma	ident	"@(#)bsd.cc	1.6	06/12/12"
+
+#include <signal.h>
+
+#include <bsd/bsd.h>
+
+/* External references.
+ */
+
+/* Forward references.
+ */
+
+/* Static data.
+ */
+
+extern SIG_PF
+bsd_signal (int Signal, SIG_PF Handler)
+{
+  auto SIG_PF                   previous_handler;
+#ifdef SUN5_0
+#ifdef sun
+  previous_handler = sigset (Signal, Handler);
+#else
+  auto struct sigaction         new_action;
+  auto struct sigaction         old_action;
+
+  new_action.sa_flags = SA_SIGINFO;
+  new_action.sa_handler = (void (*) ()) Handler;
+  (void) sigemptyset (&new_action.sa_mask);
+  (void) sigaddset (&new_action.sa_mask, Signal);
+
+  (void) sigaction (Signal, &new_action, &old_action);
+
+  previous_handler = (SIG_PF) old_action.sa_handler;
+#endif
+#elif defined(linux)
+  previous_handler = sigset (Signal, Handler);
+#else
+  previous_handler = signal (Signal, Handler);
+#endif
+  return previous_handler;
+}
+
+extern void
+bsd_signals (void)
+{
+  static int                    initialized = 0;
+
+  if (initialized == 0)
+    {
+      initialized = 1;
+#if !defined(SUN5_0) && !defined(linux)
+#if defined(SIGHUP)
+      (void) bsd_signal (SIGHUP, SIG_DFL);
+#endif
+#if defined(SIGINT)
+      (void) bsd_signal (SIGINT, SIG_DFL);
+#endif
+#if defined(SIGQUIT)
+      (void) bsd_signal (SIGQUIT, SIG_DFL);
+#endif
+#if defined(SIGILL)
+      (void) bsd_signal (SIGILL, SIG_DFL);
+#endif
+#if defined(SIGTRAP)
+      (void) bsd_signal (SIGTRAP, SIG_DFL);
+#endif
+#if defined(SIGIOT)
+      (void) bsd_signal (SIGIOT, SIG_DFL);
+#endif
+#if defined(SIGABRT)
+      (void) bsd_signal (SIGABRT, SIG_DFL);
+#endif
+#if defined(SIGEMT)
+      (void) bsd_signal (SIGEMT, SIG_DFL);
+#endif
+#if defined(SIGFPE)
+      (void) bsd_signal (SIGFPE, SIG_DFL);
+#endif
+#if defined(SIGBUS)
+      (void) bsd_signal (SIGBUS, SIG_DFL);
+#endif
+#if defined(SIGSEGV)
+      (void) bsd_signal (SIGSEGV, SIG_DFL);
+#endif
+#if defined(SIGSYS)
+      (void) bsd_signal (SIGSYS, SIG_DFL);
+#endif
+#if defined(SIGPIPE)
+      (void) bsd_signal (SIGPIPE, SIG_DFL);
+#endif
+#if defined(SIGALRM)
+      (void) bsd_signal (SIGALRM, SIG_DFL);
+#endif
+#if defined(SIGTERM)
+      (void) bsd_signal (SIGTERM, SIG_DFL);
+#endif
+#if defined(SIGUSR1)
+      (void) bsd_signal (SIGUSR1, SIG_DFL);
+#endif
+#if defined(SIGUSR2)
+      (void) bsd_signal (SIGUSR2, SIG_DFL);
+#endif
+#if defined(SIGCLD)
+      (void) bsd_signal (SIGCLD, SIG_DFL);
+#endif
+#if defined(SIGCHLD)
+      (void) bsd_signal (SIGCHLD, SIG_DFL);
+#endif
+#if defined(SIGPWR)
+      (void) bsd_signal (SIGPWR, SIG_DFL);
+#endif
+#if defined(SIGWINCH)
+      (void) bsd_signal (SIGWINCH, SIG_DFL);
+#endif
+#if defined(SIGURG)
+      (void) bsd_signal (SIGURG, SIG_DFL);
+#endif
+#if defined(SIGIO)
+      (void) bsd_signal (SIGIO, SIG_DFL);
+#else
+#if defined(SIGPOLL)
+      (void) bsd_signal (SIGPOLL, SIG_DFL);
+#endif
+#endif
+#if defined(SIGTSTP)
+      (void) bsd_signal (SIGTSTP, SIG_DFL);
+#endif
+#if defined(SIGCONT)
+      (void) bsd_signal (SIGCONT, SIG_DFL);
+#endif
+#if defined(SIGTTIN)
+      (void) bsd_signal (SIGTTIN, SIG_DFL);
+#endif
+#if defined(SIGTTOU)
+      (void) bsd_signal (SIGTTOU, SIG_DFL);
+#endif
+#if defined(SIGVTALRM)
+      (void) bsd_signal (SIGVTALRM, SIG_DFL);
+#endif
+#if defined(SIGPROF)
+      (void) bsd_signal (SIGPROF, SIG_DFL);
+#endif
+#if defined(SIGXCPU)
+      (void) bsd_signal (SIGXCPU, SIG_DFL);
+#endif
+#if defined(SIGXFSZ)
+      (void) bsd_signal (SIGXFSZ, SIG_DFL);
+#endif
+#endif
+    }
+
+  return;
+}
--- /dev/null	2015-05-20 11:04:18.000000000 -0400
+++ new/usr/src/cmd/make/lib/makestate/Makefile	2015-05-20 11:04:18.434209418 -0400
@@ -0,0 +1,48 @@
+#
+# 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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.7 06/12/12
+#
+
+TOP =		../../..
+include $(TOP)/rules/variant.mk
+
+V9_VARIANT :sh= \
+if [ -x /usr/bin/isalist ] ; \
+then \
+    for f in `/usr/bin/isalist` ; \
+    do \
+	if [ "$f" = sparcv9 ] ; \
+	then \
+	    echo sparcv9 ; \
+	    break ; \
+	fi ; \
+	if [ "$f" = amd64 ] ; \
+	then \
+	    echo amd64-S2 ; \
+	    break ; \
+	fi ; \
+    done ; \
+fi
+
+include $(TOP)/rules/derived.mk
--- /dev/null	2015-05-20 11:04:18.000000000 -0400
+++ new/usr/src/cmd/make/lib/makestate/src/Makefile	2015-05-20 11:04:18.622792507 -0400
@@ -0,0 +1,50 @@
+#
+# 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 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.5 06/12/12
+#
+# @(#)Makefile	1.1	96/03/11 SMI
+
+# Generic makefile for use in src directories.  Knows how to make common things
+# in the right $(VARIANT) directory.
+
+include $(TOP)/rules/variant.mk
+
+all :=		TARG = all 
+install :=		TARG = install 
+clean :=		TARG = clean 
+test :=		TARG = test
+l10n_install :=	TARG = l10n_install
+i18n_install :=	TARG = i18n_install
+
+SRC =		../src
+MFLAGS += 	SRC=$(SRC)
+
+# See $(TOP)/rules/master.mk for how these are built.
+%.h %.cc %.C %.E %.o all install clean test l10n_install i18n_install: FRC
+	@ if [ ! -d ../$(VARIANT) ]; then \
+		mkdir ../$(VARIANT) ; \
+	fi
+	cd ../$(VARIANT); $(MAKE) $(MFLAGS) -f $(SRC)/Variant.mk DESTDIR=$(DESTDIR) $@
+
+FRC:
--- /dev/null	2015-05-20 11:04:18.000000000 -0400
+++ new/usr/src/cmd/make/lib/makestate/src/Variant.mk	2015-05-20 11:04:18.812535256 -0400
@@ -0,0 +1,73 @@
+#
+# 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 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Variant.mk 1.12 06/12/12
+#
+
+TOP =		../../../..
+
+%.o: $(SRC)/%.c
+	$(COMPILE.c) $(OUTPUT_OPTION) $<
+
+include $(TOP)/rules/master.mk
+
+PKG_TOP =	$(TOP)/Make
+
+CSRCS =	\
+		ld_file.c \
+		lock.c
+
+LIBNAME =	libmakestate.a
+DLIBNAME =	libmakestate.so.1
+MSG_FILE = libmakestate.msg
+I18N_DIRS = $(SRC)
+
+CFLAGS += $(V9FLAGS) -KPIC -DTEXT_DOMAIN=\"SUNW_OST_OSLIB\"
+CPPFLAGS=
+
+#include $(TOP)/Make/lib/Lib.mk
+include $(TOP)/rules/lib.mk
+
+POUND_SIGN:sh=	echo \#
+RELEASE=	5.11
+VERSION=	$(RELEASE_VER)
+PATCHID=	$(VERSION)
+DATE:sh		= date '+%B %Y'
+RELEASE_DATE=	$(DATE)
+PATCH_DATE=	$(RELEASE_DATE)
+RELEASE_CM=	"@($(POUND_SIGN))RELEASE VERSION SunOS $(RELEASE) $(PATCHID) $(PATCH_DATE)"
+
+PROCESS_COMMENT=	mcs -a $(RELEASE_CM)
+POST_PROCESS_SO=	$(PROCESS_COMMENT) $@
+
+$(DLIBNAME) : $(LIBNAME)
+	$(CC) $(V9FLAGS) -o $@ -dy -G -ztext -h $@ ld_file.o lock.o -lelf
+	mcs -d $@
+	${POST_PROCESS_SO}
+
+all: $(DLIBNAME)
+
+install: all
+	${INSTALL} -d ${DESTDIR}/usr/lib$(VAR_DIR)
+	${RM} ${DESTDIR}/usr/lib$(VAR_DIR)/$(DLIBNAME)
+	${INSTALL} $(DLIBNAME) ${DESTDIR}/usr/lib$(VAR_DIR)
--- /dev/null	2015-05-20 11:04:19.000000000 -0400
+++ new/usr/src/cmd/make/lib/makestate/src/ld_file.c	2015-05-20 11:04:19.000904698 -0400
@@ -0,0 +1,192 @@
+/*
+ * 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 1998 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)ld_file.c 1.7 06/12/12
+ */
+#pragma ident	"@(#)ld_file.c	1.7	06/12/12"
+
+#pragma init(ld_support_init)
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libelf.h>
+#include <sys/param.h>
+#include <link.h>
+
+#define	SUNPRO_DEPENDENCIES	"SUNPRO_DEPENDENCIES"
+
+/*
+ * Linked list of strings - used to keep lists of names
+ * of directories or files.
+ */
+
+struct Stritem {
+	char *		str;
+	void *		next;
+};
+
+typedef struct Stritem 	Stritem;
+
+static char 		* depend_file = NULL;
+static Stritem		* list = NULL;
+
+
+void mk_state_init()
+{
+	depend_file = getenv(SUNPRO_DEPENDENCIES);
+} /* mk_state_init() */
+
+
+
+static void
+prepend_str(Stritem **list, const char * str)
+{
+	Stritem * new;
+	char 	* newstr;
+
+	if (!(new = calloc(1, sizeof (Stritem)))) {
+		perror("libmakestate.so");
+		return;
+	} /* if */
+
+	if (!(newstr = malloc(strlen(str) + 1))) {
+		perror("libmakestate.so");
+		return;
+	} /* if */
+
+	new->str = strcpy(newstr, str);
+	new->next = *list;
+	*list = new;
+
+} /* prepend_str() */
+
+
+void
+mk_state_collect_dep(const char * file)
+{
+	/*
+	 * SUNPRO_DEPENDENCIES wasn't set, we don't collect .make.state
+	 * information.
+	 */
+	if (!depend_file)
+		return;
+
+	prepend_str(&list, file);
+
+}  /* mk_state_collect_dep() */
+
+
+void
+mk_state_update_exit()
+{
+	Stritem 	* cur;
+	char		  lockfile[MAXPATHLEN],	* err, * space, * target;
+	FILE		* ofp;
+	extern char 	* file_lock(char *, char *, int);
+
+	if (!depend_file)
+		return;
+
+	if ((space = strchr(depend_file, ' ')) == NULL)
+		return;
+	*space = '\0';
+	target = &space[1];
+
+	(void) sprintf(lockfile, "%s.lock", depend_file);
+	if ((err = file_lock(depend_file, lockfile, 0))) {
+		(void) fprintf(stderr, "%s\n", err);
+		return;
+	} /* if */
+
+	if (!(ofp = fopen(depend_file, "a")))
+		return;
+
+	if (list)
+		(void) fprintf(ofp, "%s: ", target);
+
+	for (cur = list; cur; cur = cur->next)
+		(void) fprintf(ofp, " %s", cur->str);
+
+	(void) fputc('\n', ofp);
+
+	(void) fclose(ofp);
+	(void) unlink(lockfile);
+	*space = ' ';
+
+} /* mk_state_update_exit() */
+
+static void
+/* LINTED static unused */
+ld_support_init()
+{
+	mk_state_init();
+
+} /* ld_support_init() */
+
+/* ARGSUSED */
+void
+ld_file(const char * file, const Elf_Kind ekind, int flags, Elf *elf)
+{
+	if(! ((flags & LD_SUP_DERIVED) && !(flags & LD_SUP_EXTRACTED)))
+		return;
+
+	mk_state_collect_dep(file);
+
+} /* ld_file */
+
+void
+ld_atexit(int exit_code)
+{
+	if (exit_code)
+	   return;
+	
+	mk_state_update_exit();
+
+} /* ld_atexit() */
+
+/*
+ * Supporting 64-bit objects
+ */
+void
+ld_file64(const char * file, const Elf_Kind ekind, int flags, Elf *elf)
+{
+	if(! ((flags & LD_SUP_DERIVED) && !(flags & LD_SUP_EXTRACTED)))
+		return;
+
+	mk_state_collect_dep(file);
+
+} /* ld_file64 */
+
+void
+ld_atexit64(int exit_code)
+{
+	if (exit_code)
+	   return;
+	
+	mk_state_update_exit();
+
+} /* ld_atexit64() */
--- /dev/null	2015-05-20 11:04:19.000000000 -0400
+++ new/usr/src/cmd/make/lib/makestate/src/lock.c	2015-05-20 11:04:19.207625027 -0400
@@ -0,0 +1,175 @@
+/*
+ * 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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)lock.c 1.5 06/12/12
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/errno.h>
+#include <errno.h>		/* errno */
+
+#if defined(_LP64)
+/*
+ * The symbols _sys_errlist and _sys_nerr are not visible in the
+ * LP64 libc.  Use strerror(3C) instead.
+ */
+#else  /* #_LP64 */
+extern	char *		sys_errlist[];
+extern	int		sys_nerr;
+#endif /* #_LP64 */
+
+static	void		file_lock_error();
+
+/*
+ * This code stolen from the NSE library and changed to not depend
+ * upon any NSE routines or header files.
+ *
+ * Simple file locking.
+ * Create a symlink to a file.  The "test and set" will be
+ * atomic as creating the symlink provides both functions.
+ *
+ * The timeout value specifies how long to wait for stale locks
+ * to disappear.  If the lock is more than 'timeout' seconds old
+ * then it is ok to blow it away.  This part has a small window
+ * of vunerability as the operations of testing the time,
+ * removing the lock and creating a new one are not atomic.
+ * It would be possible for two processes to both decide to blow
+ * away the lock and then have process A remove the lock and establish
+ * its own, and then then have process B remove the lock which accidentily
+ * removes A's lock rather than the stale one.
+ *
+ * A further complication is with the NFS.  If the file in question is
+ * being served by an NFS server, then its time is set by that server.
+ * We can not use the time on the client machine to check for a stale
+ * lock.  Therefore, a temp file on the server is created to get
+ * the servers current time.
+ *
+ * Returns an error message.  NULL return means the lock was obtained.
+ *
+ */
+char *
+file_lock(char * name, char * lockname, int timeout)
+{
+	int		r;
+	int		fd;
+	struct	stat	statb;
+	struct	stat	fs_statb;
+	char		tmpname[MAXPATHLEN];
+	static	char	msg[MAXPATHLEN];
+
+	if (timeout <= 0) {
+		timeout = 15;
+	}
+	for (;;) {
+		r = symlink(name, lockname);
+		if (r == 0) {
+			return (NULL);
+		}
+		if (errno != EEXIST) {
+			file_lock_error(msg, name,
+			    (const char *)"symlink(%s, %s)", name, lockname);
+			return (msg);
+		}
+		for (;;) {
+			(void) sleep(1);
+			r = lstat(lockname, &statb);
+			if (r == -1) {
+				/*
+				 * The lock must have just gone away - try
+				 * again.
+				 */
+				break;
+			}
+
+			/*
+			 * With the NFS the time given a file is the time on
+			 * the file server.  This time may vary from the
+			 * client's time.  Therefore, we create a tmpfile in
+			 * the same directory to establish the time on the
+			 * server and use this time to see if the lock has
+			 * expired.
+			 */
+			(void) sprintf(tmpname, "%s.XXXXXX", lockname);
+			(void) mktemp(tmpname);
+			fd = creat(tmpname, 0666);
+			if (fd != -1) {
+				(void) close(fd);
+			} else {
+				file_lock_error(msg, name,
+				    (const char *)"creat(%s)", tmpname);
+				return (msg);
+			}
+			if (stat(tmpname, &fs_statb) == -1) {
+				file_lock_error(msg, name,
+				    (const char *)"stat(%s)", tmpname);
+				return (msg);
+			}
+			(void) unlink(tmpname);
+			if (statb.st_mtime + timeout < fs_statb.st_mtime) {
+				/*
+				 * The lock has expired - blow it away.
+				 */
+				(void) unlink(lockname);
+				break;
+			}
+		}
+	}
+	/* NOTREACHED */
+}
+
+/*
+ * Format a message telling why the lock could not be created.
+ */
+/* VARARGS4 */
+static	void
+file_lock_error(char * msg, char * file, const char * str, char * arg1,
+	char * arg2)
+{
+	int	len;
+
+	(void) sprintf(msg, "Could not lock file `%s'; ", file);
+	len = strlen(msg);
+	(void) sprintf(&msg[len], str, arg1, arg2);
+	(void) strcat(msg, " failed - ");
+#if defined(_LP64)
+	/* Needs to be changed to use strerror(3C) instead. */
+	len = strlen(msg);
+	(void) sprintf(&msg[len], "errno %d", errno);
+#else  /* #_LP64 */
+	if (errno < sys_nerr) {
+		(void) strcat(msg, sys_errlist[errno]);
+	} else {
+		len = strlen(msg);
+		(void) sprintf(&msg[len], "errno %d", errno);
+	}
+#endif /* #_LP64 */
+}
--- /dev/null	2015-05-20 11:04:19.000000000 -0400
+++ new/usr/src/cmd/make/lib/mksdmsi18n/Makefile	2015-05-20 11:04:19.413206979 -0400
@@ -0,0 +1,30 @@
+#
+# 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 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.5 06/12/12
+#
+
+TOP		= ../../..
+include $(TOP)/rules/variant.mk
+include $(TOP)/rules/derived.mk
+
--- /dev/null	2015-05-20 11:04:19.000000000 -0400
+++ new/usr/src/cmd/make/lib/mksdmsi18n/src/Makefile	2015-05-20 11:04:19.605873606 -0400
@@ -0,0 +1,46 @@
+#
+# 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 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.10 06/12/12
+#
+
+TOP =		../../../..
+include $(TOP)/rules/master.mk
+
+SUBDIRS =	lib
+include $(TOP)/rules/recurse.mk
+include $(SRC)/lib/version.mk
+
+PKG_TOP =	$(TOP)/Make
+CPPFLAGS +=	-I$(PKG_TOP)/include
+
+CCSRCS =		libmksdmsi18n_init.cc
+
+LIBNAME =	libmksdmsi18n.a
+
+#
+# Pass in the version number for the i18n message catalog.
+#
+libmksdmsi18n_init.o :=	CPPFLAGS += -DI18N_VERSION=$(VERSION)
+
+include $(TOP)/rules/lib.mk
--- /dev/null	2015-05-20 11:04:19.000000000 -0400
+++ new/usr/src/cmd/make/lib/mksdmsi18n/src/Variant.mk	2015-05-20 11:04:19.921709373 -0400
@@ -0,0 +1,52 @@
+#
+# 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 1997 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Variant.mk 1.4 06/12/12
+#
+
+TOP =		../../../..
+include $(TOP)/rules/master.mk
+#include $(TOP)/rules/dmake.mk
+
+#SUBDIRS =	$(SRC)/lib
+#include $(TOP)/rules/recurse.mk
+
+CCSRCS = \
+		libmksdmsi18n_init.cc 
+
+CSRCS =
+
+include $(SRC)/lib/version.mk
+
+libmksdmsi18n_init.o := CPPFLAGS += -DI18N_VERSION=$(VERSION)
+
+#PKG_TOP =	$(TOP)/Make
+#CPPFLAGS +=	-I$(PKG_TOP)/include
+
+LIBNAME =	libmksdmsi18n.a
+MSG_FILE = libmksdmsi18n.msg
+I18N_DIRS = $(SRC)
+
+include $(TOP)/Make/lib/Lib.mk
+include $(TOP)/rules/lib.mk
+
--- /dev/null	2015-05-20 11:04:20.000000000 -0400
+++ new/usr/src/cmd/make/lib/mksdmsi18n/src/lib/Makefile	2015-05-20 11:04:20.112929842 -0400
@@ -0,0 +1,54 @@
+#
+# 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 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.7 06/12/12
+#
+
+include version.mk
+
+TOP		= ../../../../..
+PKG_TOP		= $(TOP)/Make
+PKG_LIB_TOP	= $(PKG_TOP)/lib
+I18N_LIBS	= bsd dmrxm dmrxs mksh vroot
+I18N_DIRS	= $(I18N_LIBS:%=$(PKG_LIB_TOP)/%/src)
+SRC		= .
+APPPATH		= .
+LIBNAME		= libmksdmsi18n
+TEXTDOMAIN	= $(LIBNAME)_$(VERSION)
+MSG_FILE	= $(TEXTDOMAIN).msg
+
+all clean:
+install: catalogs .WAIT i18n_install
+
+#
+# This is a hack until the top level makefiles for i18n/l10n message catalogs
+# are better organized and written.
+# This "catalogs" target was cp'ed from $(TOP)/rules/lib.mk
+#
+catalogs:
+	$(GENMSG) -l $(SRC)/genmsg.project -o $(MSG_FILE) `find $(I18N_DIRS) \( -name '*.cc' -o -name '*.c' -o -name '*.y' \) -print | grep -v /SCCS/`
+	rm -f *.cc.new
+
+include $(PKG_TOP)/prodver.mk
+include $(TOP)/rules/i18n-install.mk
+
--- /dev/null	2015-05-20 11:04:20.000000000 -0400
+++ new/usr/src/cmd/make/lib/mksdmsi18n/src/lib/version.mk	2015-05-20 11:04:20.331394373 -0400
@@ -0,0 +1,30 @@
+#
+# 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 1995 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)version.mk 1.2 06/12/12
+#
+
+# A version number is needed to version the i18n catalog file
+
+VERSION = 1
+
--- /dev/null	2015-05-20 11:04:20.000000000 -0400
+++ new/usr/src/cmd/make/lib/mksdmsi18n/src/libmksdmsi18n_init.cc	2015-05-20 11:04:20.519586219 -0400
@@ -0,0 +1,63 @@
+/*
+ * 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 1996 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)libmksdmsi18n_init.cc 1.5 06/12/12
+ */
+
+#pragma	ident	"@(#)libmksdmsi18n_init.cc	1.5	06/12/12"
+
+#include <avo/intl.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+nl_catd libmksdmsi18n_catd;
+ 
+/*
+ * Open the catalog file for libmksdmsi18n.  Users of this library must set
+ * NSLPATH first.  See avo_18n_init().
+ */
+int
+libmksdmsi18n_init()
+{
+	char		name[20];
+
+	if (getenv(NOCATGETS("NLSPATH")) == NULL) {
+		fprintf(stderr, NOCATGETS("Internal error: Set NLSPATH before opening catalogue file\n"));
+		return 1;
+	}
+	sprintf(name, NOCATGETS("libmksdmsi18n_%d"), I18N_VERSION);
+	libmksdmsi18n_catd = catopen(name, NL_CAT_LOCALE);
+	return 0;
+}
+ 
+/*
+ * Close the catalog file for libmksdmsi18n
+ */
+void
+libmksdmsi18n_fini()
+{
+	catclose(libmksdmsi18n_catd);
+}
+
--- /dev/null	2015-05-20 11:04:20.000000000 -0400
+++ new/usr/src/cmd/make/lib/mksh/Makefile	2015-05-20 11:04:20.718235258 -0400
@@ -0,0 +1,29 @@
+#
+# 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 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.5 06/12/12
+#
+
+TOP =		../../..
+include $(TOP)/rules/variant.mk
+include $(TOP)/rules/derived.mk
--- /dev/null	2015-05-20 11:04:20.000000000 -0400
+++ new/usr/src/cmd/make/lib/mksh/src/Makefile	2015-05-20 11:04:20.921894125 -0400
@@ -0,0 +1,50 @@
+#
+# 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 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.3 06/12/12
+#
+
+# Generic makefile for use in src directories.  Knows how to make common things
+# in the right $(VARIANT) directory.
+
+#TOP =		../../../..
+include $(TOP)/rules/variant.mk
+
+all :=		TARG = all 
+install :=		TARG = install 
+clean :=		TARG = clean 
+test :=		TARG = test
+l10n_install :=	TARG = l10n_install
+i18n_install :=	TARG = i18n_install
+
+SRC =		../src
+MFLAGS += 	SRC=$(SRC)
+
+# See $(TOP)/rules/master.mk for how these are built.
+%.h %.cc %.C %.E %.o all install clean test l10n_install i18n_install: FRC
+	@ if [ ! -d ../$(VARIANT) ]; then \
+		mkdir ../$(VARIANT) ; \
+	fi
+	cd ../$(VARIANT); $(MAKE) $(MFLAGS) -f $(SRC)/Variant.mk DESTDIR=$(DESTDIR) $@
+
+FRC:
--- /dev/null	2015-05-20 11:04:21.000000000 -0400
+++ new/usr/src/cmd/make/lib/mksh/src/Variant.mk	2015-05-20 11:04:21.110799069 -0400
@@ -0,0 +1,58 @@
+#
+# 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 2002 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Variant.mk 1.19 06/12/12
+#
+
+TOP =		 ../../../..
+include $(TOP)/rules/master.mk
+include $(TOP)/rules/dmake.mk
+
+PKG_TOP =	$(TOP)/Make
+CPPFLAGS +=	-I$(PKG_TOP)/include
+
+CCSRCS =	\
+		dosys.cc \
+		globals.cc \
+		i18n.cc \
+		macro.cc \
+		misc.cc \
+		mksh.cc \
+		read.cc
+
+HDRS_DIR =	$(PKG_TOP)/include/mksh
+HDRS_LIST =	$(HDRS_DIR)/defs.h \
+		$(CCSRCS:%.cc=$(HDRS_DIR)/%.h) \
+		$(CSRCS:%.c=$(HDRS_DIR)/%.h)
+
+.INIT: $(HDRS_LIST)
+
+LIBNAME =	libmksh.a
+MSG_FILE = libmksh.msg
+I18N_DIRS = $(SRC)
+
+#CPPFLAGS	+= -DTEAMWARE_MAKE_CMN -DDISTRIBUTED
+
+include $(TOP)/Make/lib/Lib.mk
+include $(TOP)/rules/lib.mk
+
--- /dev/null	2015-05-20 11:04:21.000000000 -0400
+++ new/usr/src/cmd/make/lib/mksh/src/dosys.cc	2015-05-20 11:04:21.329616295 -0400
@@ -0,0 +1,851 @@
+/*
+ * 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 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)dosys.cc 1.38 06/12/12
+ */
+
+#pragma	ident	"@(#)dosys.cc	1.38	06/12/12"
+
+/*
+ *	dosys.cc
+ *
+ *	Execute one commandline
+ */
+
+/*
+ * Included files
+ */
+#include <sys/wait.h>			/* WIFEXITED(status) */
+#include <avo/avo_alloca.h>		/* alloca() */
+
+#if defined(TEAMWARE_MAKE_CMN) || defined(MAKETOOL) /* tolik */
+#	include <avo/strings.h>	/* AVO_STRDUP() */
+#if defined(DISTRIBUTED)
+#	include <dm/Avo_CmdOutput.h>
+#	include <rw/xdrstrea.h>
+#endif
+#endif
+
+#include <stdio.h>		/* errno */
+#include <errno.h>		/* errno */
+#include <fcntl.h>		/* open() */
+#include <mksh/dosys.h>
+#include <mksh/macro.h>		/* getvar() */
+#include <mksh/misc.h>		/* getmem(), fatal_mksh(), errmsg() */
+#include <mksdmsi18n/mksdmsi18n.h>	/* libmksdmsi18n_init() */
+#include <sys/signal.h>		/* SIG_DFL */
+#include <sys/stat.h>		/* open() */
+#include <sys/wait.h>		/* wait() */
+#include <ulimit.h>		/* ulimit() */
+#include <unistd.h>		/* close(), dup2() */
+
+#if defined (HP_UX) || defined (linux)
+#	include <sys/param.h>
+#	include <wctype.h>
+#	include <wchar.h>
+#endif
+
+#if defined (linux)
+#	define wslen(x) wcslen(x)
+#	define wscpy(x,y) wcscpy(x,y)
+#endif
+
+/*
+ * Defined macros
+ */
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+#define SEND_MTOOL_MSG(cmds) \
+	if (send_mtool_msgs) { \
+		cmds \
+	}
+#else
+#define SEND_MTOOL_MSG(cmds)
+#endif
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+
+/*
+ * File table of contents
+ */
+static Boolean	exec_vp(register char *name, register char **argv, char **envp, register Boolean ignore_error, pathpt vroot_path);
+
+/*
+ * Workaround for NFS bug. Sometimes, when running 'open' on a remote
+ * dmake server, it fails with "Stale NFS file handle" error.
+ * The second attempt seems to work.
+ */
+int
+my_open(const char *path, int oflag, mode_t mode) {
+	int res = open(path, oflag, mode);
+#ifdef linux
+// Workaround for NFS problem: even when all directories in 'path'
+// exist, 'open' (file creation) fails with ENOENT.
+	int nattempt = 0;
+	while (res < 0 && (errno == ESTALE || errno == EAGAIN || errno == ENOENT)) {
+		nattempt++;
+		if(nattempt > 30) {
+			break;
+		}
+		sleep(1);
+#else
+	if (res < 0 && (errno == ESTALE || errno == EAGAIN)) {
+#endif
+		/* Stale NFS file handle. Try again */
+		res = open(path, oflag, mode);
+	}
+	return res;
+}
+
+/*
+ *	void
+ *	redirect_io(char *stdout_file, char *stderr_file)
+ *
+ *	Redirects stdout and stderr for a child mksh process.
+ */
+void
+redirect_io(char *stdout_file, char *stderr_file)
+{        
+	long		descriptor_limit;
+	int		i;
+
+#if defined (HP_UX) || defined (linux)
+        /*
+         *  HP-UX does not support the UL_GDESLIM command for ulimit().
+	 *  NOFILE == max num open files per process (from <sys/param.h>)
+         */
+	descriptor_limit = NOFILE;
+#else
+	if ((descriptor_limit = ulimit(UL_GDESLIM)) < 0) {
+		fatal_mksh(catgets(libmksdmsi18n_catd, 1, 89, "ulimit() failed: %s"), errmsg(errno));
+	}
+#endif
+	for (i = 3; i < descriptor_limit; i++) {
+		(void) close(i);
+	}
+	if ((i = my_open(stdout_file,
+	         O_WRONLY | O_CREAT | O_TRUNC | O_DSYNC,
+	         S_IREAD | S_IWRITE)) < 0) {
+		fatal_mksh(catgets(libmksdmsi18n_catd, 1, 90, "Couldn't open standard out temp file `%s': %s"),
+		      stdout_file,
+		      errmsg(errno));
+	} else {
+		if (dup2(i, 1) == -1) {
+			fatal_mksh(NOCATGETS("*** Error: dup2(3, 1) failed: %s"),
+				errmsg(errno));
+		}
+		close(i);
+	}
+	if (stderr_file == NULL) {
+		if (dup2(1, 2) == -1) {
+			fatal_mksh(NOCATGETS("*** Error: dup2(1, 2) failed: %s"),
+				errmsg(errno));
+		}
+	} else if ((i = my_open(stderr_file,
+	                O_WRONLY | O_CREAT | O_TRUNC | O_DSYNC,
+	                S_IREAD | S_IWRITE)) < 0) {
+		fatal_mksh(catgets(libmksdmsi18n_catd, 1, 91, "Couldn't open standard error temp file `%s': %s"),
+		      stderr_file,
+		      errmsg(errno));
+	} else {
+		if (dup2(i, 2) == -1) {
+			fatal_mksh(NOCATGETS("*** Error: dup2(3, 2) failed: %s"),
+				errmsg(errno));
+		}
+		close(i);
+	}
+}
+
+/*
+ *	dosys_mksh(command, ignore_error, call_make, silent_error, target)
+ *
+ *	Check if command string contains meta chars and dispatch to
+ *	the proper routine for executing one command line.
+ *
+ *	Return value:
+ *				Indicates if the command execution failed
+ *
+ *	Parameters:
+ *		command		The command to run
+ *		ignore_error	Should we abort when an error is seen?
+ *		call_make	Did command reference $(MAKE) ?
+ *		silent_error	Should error messages be suppressed for dmake?
+ *		target		Target we are building
+ *
+ *	Global variables used:
+ *		do_not_exec_rule Is -n on?
+ *		working_on_targets We started processing real targets
+ */
+Doname
+dosys_mksh(register Name command, register Boolean ignore_error, register Boolean call_make, Boolean silent_error, Boolean always_exec, Name target, Boolean redirect_out_err, char *stdout_file, char *stderr_file, pathpt vroot_path, int nice_prio)
+{
+	register int		length = command->hash.length;
+	register wchar_t	*p;
+	register wchar_t	*q;
+	register wchar_t	*cmd_string;
+	struct stat		before;
+	Doname			result;
+	Boolean			working_on_targets_mksh = true;
+	Wstring wcb(command);
+	p = wcb.get_string();
+	cmd_string = p;
+
+	/* Strip spaces from head of command string */
+	while (iswspace(*p)) {
+		p++, length--;
+	}
+	if (*p == (int) nul_char) {
+		return build_failed;
+	}
+	/* If we are faking it we just return */
+	if (do_not_exec_rule &&
+	    working_on_targets_mksh &&
+	    !call_make &&
+	    !always_exec) {
+		return build_ok;
+	}
+
+	/* Copy string to make it OK to write it. */
+	q = ALLOC_WC(length + 1);
+	(void) wscpy(q, p);
+	/* Write the state file iff this command uses make. */
+/* XXX - currently does not support recursive make's, $(MAKE)'s
+	if (call_make && command_changed) {
+		write_state_file(0, false);
+	}
+	(void) stat(make_state->string_mb, &before);
+ */
+	/*
+	 * Run command directly if it contains no shell meta chars,
+	 * else run it using the shell.
+	 */
+	/* XXX - command->meta *may* not be set correctly */
+	if (await(ignore_error,
+		  silent_error,
+		  target,
+		  cmd_string,
+                  command->meta ?
+	            doshell(q, ignore_error, redirect_out_err, stdout_file, stderr_file, nice_prio) :
+	            doexec(q, ignore_error, redirect_out_err, stdout_file, stderr_file, vroot_path, nice_prio),
+	          false,
+	          NULL,
+	          -1)) {
+
+#ifdef PRINT_EXIT_STATUS
+		warning_mksh(NOCATGETS("I'm in dosys_mksh(), and await() returned result of build_ok."));
+#endif
+
+		result = build_ok;
+	} else {
+
+#ifdef PRINT_EXIT_STATUS
+		warning_mksh(NOCATGETS("I'm in dosys_mksh(), and await() returned result of build_failed."));
+#endif
+
+		result = build_failed;
+	}
+	retmem(q);
+
+/* XXX - currently does not support recursive make's, $(MAKE)'s
+	if ((report_dependencies_level == 0) &&
+	    call_make) {
+		make_state->stat.time = (time_t)file_no_time;
+		(void)exists(make_state);
+		if (before.st_mtime == make_state->stat.time) {
+			return result;
+		}
+		makefile_type = reading_statefile;
+		if (read_trace_level > 1) {
+			trace_reader = true;
+		}
+		(void) read_simple_file(make_state,
+					false,
+					false,
+					false,
+					false,
+					false,
+					true);
+		trace_reader = false;
+	}
+ */
+	return result;
+}
+
+/*
+ *	doshell(command, ignore_error)
+ *
+ *	Used to run command lines that include shell meta-characters.
+ *	The make macro SHELL is supposed to contain a path to the shell.
+ *
+ *	Return value:
+ *				The pid of the process we started
+ *
+ *	Parameters:
+ *		command		The command to run
+ *		ignore_error	Should we abort on error?
+ *
+ *	Global variables used:
+ *		filter_stderr	If -X is on we redirect stderr
+ *		shell_name	The Name "SHELL", used to get the path to shell
+ */
+int
+doshell(wchar_t *command, register Boolean ignore_error, Boolean redirect_out_err, char *stdout_file, char *stderr_file, int nice_prio)
+{
+	char			*argv[6];
+	int			argv_index = 0;
+	int			cmd_argv_index;
+	int			length;
+	char			nice_prio_buf[MAXPATHLEN];
+	register Name		shell = getvar(shell_name);
+	register char		*shellname;
+	char			*tmp_mbs_buffer;
+
+
+	if (IS_EQUAL(shell->string_mb, "")) {
+		shell = shell_name;
+	}
+	if ((shellname = strrchr(shell->string_mb, (int) slash_char)) == NULL) {
+		shellname = shell->string_mb;
+	} else {
+		shellname++;
+	}
+
+	/*
+	 * Only prepend the /usr/bin/nice command to the original command
+	 * if the nice priority, nice_prio, is NOT zero (0).
+	 * Nice priorities can be a positive or a negative number.
+	 */
+	if (nice_prio != 0) {
+		argv[argv_index++] = NOCATGETS("nice");
+		(void) sprintf(nice_prio_buf, NOCATGETS("-%d"), nice_prio);
+		argv[argv_index++] = strdup(nice_prio_buf);
+	}
+	argv[argv_index++] = shellname;
+#if defined(linux)
+	if(0 == strcmp(shell->string_mb, (char*)NOCATGETS("/bin/sh"))) {
+		argv[argv_index++] = (char*)(ignore_error ? NOCATGETS("-c") : NOCATGETS("-ce"));
+	} else {
+		argv[argv_index++] = (char*)NOCATGETS("-c");
+	}
+#else
+	argv[argv_index++] = (char*)(ignore_error ? NOCATGETS("-c") : NOCATGETS("-ce"));
+#endif
+	if ((length = wslen(command)) >= MAXPATHLEN) {
+		tmp_mbs_buffer = getmem((length * MB_LEN_MAX) + 1);
+                (void) wcstombs(tmp_mbs_buffer, command, (length * MB_LEN_MAX) + 1);
+		cmd_argv_index = argv_index;
+                argv[argv_index++] = strdup(tmp_mbs_buffer);
+                retmem_mb(tmp_mbs_buffer);
+	} else {
+		WCSTOMBS(mbs_buffer, command);
+		cmd_argv_index = argv_index;
+#if defined(linux)
+		int mbl = strlen(mbs_buffer);
+		if(mbl > 2) {
+			if(mbs_buffer[mbl-1] == '\n' && mbs_buffer[mbl-2] == '\\') {
+				mbs_buffer[mbl] = '\n';
+				mbs_buffer[mbl+1] = 0;
+			}
+		}
+#endif
+		argv[argv_index++] = strdup(mbs_buffer);
+	}
+	argv[argv_index] = NULL;
+	(void) fflush(stdout);
+	if ((childPid = fork()) == 0) {
+		enable_interrupt((void (*) (int)) SIG_DFL);
+		if (redirect_out_err) {
+			redirect_io(stdout_file, stderr_file);
+		}
+#if 0
+		if (filter_stderr) {
+			redirect_stderr();
+		}
+#endif
+		if (nice_prio != 0) {
+			(void) execve(NOCATGETS("/usr/bin/nice"), argv, environ);
+			fatal_mksh(catgets(libmksdmsi18n_catd, 1, 92, "Could not load `/usr/bin/nice': %s"),
+			      errmsg(errno));
+		} else {
+			(void) execve(shell->string_mb, argv, environ);
+			fatal_mksh(catgets(libmksdmsi18n_catd, 1, 93, "Could not load Shell from `%s': %s"),
+			      shell->string_mb,
+			      errmsg(errno));
+		}
+	}
+	if (childPid  == -1) {
+		fatal_mksh(catgets(libmksdmsi18n_catd, 1, 94, "fork failed: %s"),
+		      errmsg(errno));
+	}
+	retmem_mb(argv[cmd_argv_index]);
+	return childPid;
+}
+
+/*
+ *	exec_vp(name, argv, envp, ignore_error)
+ *
+ *	Like execve, but does path search.
+ *	This starts command when make invokes it directly (without a shell).
+ *
+ *	Return value:
+ *				Returns false if the exec failed
+ *
+ *	Parameters:
+ *		name		The name of the command to run
+ *		argv		Arguments for the command
+ *		envp		The environment for it
+ *		ignore_error	Should we abort on error?
+ *
+ *	Global variables used:
+ *		shell_name	The Name "SHELL", used to get the path to shell
+ *		vroot_path	The path used by the vroot package
+ */
+static Boolean
+exec_vp(register char *name, register char **argv, char **envp, register Boolean ignore_error, pathpt vroot_path)
+{
+	register Name		shell = getvar(shell_name);
+	register char		*shellname;
+	char			*shargv[4];
+	Name			tmp_shell;
+
+	if (IS_EQUAL(shell->string_mb, "")) {
+		shell = shell_name;
+	}
+
+	for (int i = 0; i < 5; i++) {
+		(void) execve_vroot(name,
+				    argv + 1,
+				    envp,
+				    vroot_path,
+				    VROOT_DEFAULT);
+		switch (errno) {
+		case ENOEXEC:
+		case ENOENT:
+			/* That failed. Let the shell handle it */
+			shellname = strrchr(shell->string_mb, (int) slash_char);
+			if (shellname == NULL) {
+				shellname = shell->string_mb;
+			} else {
+				shellname++;
+			}
+			shargv[0] = shellname;
+			shargv[1] = (char*)(ignore_error ? NOCATGETS("-c") : NOCATGETS("-ce"));
+			shargv[2] = argv[0];
+			shargv[3] = NULL;
+			tmp_shell = getvar(shell_name);
+			if (IS_EQUAL(tmp_shell->string_mb, "")) {
+				tmp_shell = shell_name;
+			}
+			(void) execve_vroot(tmp_shell->string_mb,
+					    shargv,
+					    envp,
+					    vroot_path,
+					    VROOT_DEFAULT);
+			return failed;
+		case ETXTBSY:
+			/*
+			 * The program is busy (debugged?).
+			 * Wait and then try again.
+			 */
+			(void) sleep((unsigned) i);
+		case EAGAIN:
+			break;
+		default:
+			return failed;
+		}
+	}
+	return failed;
+}
+
+/*
+ *	doexec(command, ignore_error)
+ *
+ *	Will scan an argument string and split it into words
+ *	thus building an argument list that can be passed to exec_ve()
+ *
+ *	Return value:
+ *				The pid of the process started here
+ *
+ *	Parameters:
+ *		command		The command to run
+ *		ignore_error	Should we abort on error?
+ *
+ *	Global variables used:
+ *		filter_stderr	If -X is on we redirect stderr
+ */
+int
+doexec(register wchar_t *command, register Boolean ignore_error, Boolean redirect_out_err, char *stdout_file, char *stderr_file, pathpt vroot_path, int nice_prio)
+{
+	int			arg_count = 5;
+	char			**argv;
+	int			length;
+	char			nice_prio_buf[MAXPATHLEN];
+	register char		**p;
+	wchar_t			*q;
+	register wchar_t	*t;
+	char			*tmp_mbs_buffer;
+
+	/*
+	 * Only prepend the /usr/bin/nice command to the original command
+	 * if the nice priority, nice_prio, is NOT zero (0).
+	 * Nice priorities can be a positive or a negative number.
+	 */
+	if (nice_prio != 0) {
+		arg_count += 2;
+	}
+	for (t = command; *t != (int) nul_char; t++) {
+		if (iswspace(*t)) {
+			arg_count++;
+		}
+	}
+	argv = (char **)alloca(arg_count * (sizeof(char *)));
+	/*
+	 * Reserve argv[0] for sh in case of exec_vp failure.
+	 * Don't worry about prepending /usr/bin/nice command to argv[0].
+	 * In fact, doing it may cause the sh command to fail!
+	 */
+	p = &argv[1];
+	if ((length = wslen(command)) >= MAXPATHLEN) {
+		tmp_mbs_buffer = getmem((length * MB_LEN_MAX) + 1);
+		(void) wcstombs(tmp_mbs_buffer, command, (length * MB_LEN_MAX) + 1);
+		argv[0] = strdup(tmp_mbs_buffer);
+		retmem_mb(tmp_mbs_buffer);
+        } else {
+		WCSTOMBS(mbs_buffer, command);
+		argv[0] = strdup(mbs_buffer);
+	}
+
+	if (nice_prio != 0) {
+		*p++ = strdup(NOCATGETS("/usr/bin/nice"));
+		(void) sprintf(nice_prio_buf, NOCATGETS("-%d"), nice_prio);
+		*p++ = strdup(nice_prio_buf);
+	}
+	/* Build list of argument words. */
+	for (t = command; *t;) {
+		if (p >= &argv[arg_count]) {
+			/* This should never happen, right? */
+			WCSTOMBS(mbs_buffer, command);
+			fatal_mksh(catgets(libmksdmsi18n_catd, 1, 95, "Command `%s' has more than %d arguments"),
+			      mbs_buffer,
+			      arg_count);
+		}
+		q = t;
+		while (!iswspace(*t) && (*t != (int) nul_char)) {
+			t++;
+		}
+		if (*t) {
+			for (*t++ = (int) nul_char; iswspace(*t); t++);
+		}
+		if ((length = wslen(q)) >= MAXPATHLEN) {
+			tmp_mbs_buffer = getmem((length * MB_LEN_MAX) + 1);
+			(void) wcstombs(tmp_mbs_buffer, q, (length * MB_LEN_MAX) + 1);
+			*p++ = strdup(tmp_mbs_buffer);
+			retmem_mb(tmp_mbs_buffer);
+		} else {
+			WCSTOMBS(mbs_buffer, q);
+			*p++ = strdup(mbs_buffer);
+		}
+	}
+	*p = NULL;
+
+	/* Then exec the command with that argument list. */
+	(void) fflush(stdout);
+	if ((childPid = fork()) == 0) {
+		enable_interrupt((void (*) (int)) SIG_DFL);
+		if (redirect_out_err) {
+			redirect_io(stdout_file, stderr_file);
+		}
+#if 0
+		if (filter_stderr) {
+			redirect_stderr();
+		}
+#endif
+		(void) exec_vp(argv[1], argv, environ, ignore_error, vroot_path);
+		fatal_mksh(catgets(libmksdmsi18n_catd, 1, 96, "Cannot load command `%s': %s"), argv[1], errmsg(errno));
+	}
+	if (childPid  == -1) {
+		fatal_mksh(catgets(libmksdmsi18n_catd, 1, 97, "fork failed: %s"),
+		      errmsg(errno));
+	}
+	for (int i = 0; argv[i] != NULL; i++) {
+		retmem_mb(argv[i]);
+	}
+	return childPid;
+}
+
+/*
+ *	await(ignore_error, silent_error, target, command, running_pid)
+ *
+ *	Wait for one child process and analyzes
+ *	the returned status when the child process terminates.
+ *
+ *	Return value:
+ *				Returns true if commands ran OK
+ *
+ *	Parameters:
+ *		ignore_error	Should we abort on error?
+ *		silent_error	Should error messages be suppressed for dmake?
+ *		target		The target we are building, for error msgs
+ *		command		The command we ran, for error msgs
+ *		running_pid	The pid of the process we are waiting for
+ *		
+ *	Static variables used:
+ *		filter_file	The fd for the filter file
+ *		filter_file_name The name of the filter file
+ *
+ *	Global variables used:
+ *		filter_stderr	Set if -X is on
+ */
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+Boolean
+await(register Boolean ignore_error, register Boolean silent_error, Name target, wchar_t *command, pid_t running_pid, Boolean send_mtool_msgs, XDR *xdrs_p, int job_msg_id)
+#else
+Boolean
+await(register Boolean ignore_error, register Boolean silent_error, Name target, wchar_t *command, pid_t running_pid, Boolean send_mtool_msgs, void *xdrs_p, int job_msg_id)
+#endif
+{
+#ifdef SUN5_0
+        int                     status;
+#else
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(stat)       stat.w_T.w_Retcode
+#endif
+#ifndef WTERMSIG
+#define WTERMSIG(stat)          stat.w_T.w_Termsig
+#endif
+#ifndef WCOREDUMP
+#define WCOREDUMP(stat)         stat.w_T.w_Coredump
+#endif
+#if defined (HP_UX) || defined (linux)
+	int			status;
+#else
+	union wait		status;
+#endif
+#endif
+	char			*buffer;
+	int			core_dumped;
+	int			exit_status;
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+	Avo_CmdOutput		*make_output_msg;
+#endif
+	FILE			*outfp;
+	register pid_t		pid;
+	struct stat		stat_buff;
+	int			termination_signal;
+	char			tmp_buf[MAXPATHLEN];
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+	RWCollectable		*xdr_msg;
+#endif
+
+	while ((pid = wait(&status)) != running_pid) {
+		if (pid == -1) {
+			fatal_mksh(catgets(libmksdmsi18n_catd, 1, 98, "wait() failed: %s"), errmsg(errno));
+		}
+	}
+	(void) fflush(stdout);
+	(void) fflush(stderr);
+
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+        if (status == 0) {
+
+#ifdef PRINT_EXIT_STATUS
+		warning_mksh(NOCATGETS("I'm in await(), and status is 0."));
+#endif
+
+                return succeeded;
+	}
+
+#ifdef PRINT_EXIT_STATUS
+	warning_mksh(NOCATGETS("I'm in await(), and status is *NOT* 0."));
+#endif
+
+#else
+        if (status.w_status == 0) {
+                return succeeded;
+	}
+#endif
+
+        exit_status = WEXITSTATUS(status);
+
+#ifdef PRINT_EXIT_STATUS
+	warning_mksh(NOCATGETS("I'm in await(), and exit_status is %d."), exit_status);
+#endif
+
+        termination_signal = WTERMSIG(status);
+        core_dumped = WCOREDUMP(status);
+
+	/*
+	 * If the child returned an error, we now try to print a
+	 * nice message about it.
+	 */
+	SEND_MTOOL_MSG(
+		make_output_msg = new Avo_CmdOutput();
+		(void) sprintf(tmp_buf, "%d", job_msg_id);
+		make_output_msg->appendOutput(AVO_STRDUP(tmp_buf));
+	);
+
+	tmp_buf[0] = (int) nul_char;
+	if (!silent_error) {
+		if (exit_status != 0) {
+			(void) fprintf(stdout,
+				       catgets(libmksdmsi18n_catd, 1, 103, "*** Error code %d"),
+				       exit_status);
+			SEND_MTOOL_MSG(
+				(void) sprintf(&tmp_buf[strlen(tmp_buf)],
+					       catgets(libmksdmsi18n_catd, 1, 104, "*** Error code %d"),
+					       exit_status);
+			);
+		} else {
+#if ! defined(SUN5_0) && ! defined(HP_UX) && ! defined(linux)
+			if (termination_signal > NSIG) {
+#endif
+				(void) fprintf(stdout,
+					       catgets(libmksdmsi18n_catd, 1, 105, "*** Signal %d"),
+					       termination_signal);
+				SEND_MTOOL_MSG(
+					(void) sprintf(&tmp_buf[strlen(tmp_buf)],
+						       catgets(libmksdmsi18n_catd, 1, 106, "*** Signal %d"),
+						       termination_signal);
+				);
+#if ! defined(SUN5_0) && ! defined(HP_UX) && ! defined(linux)
+			} else {
+				(void) fprintf(stdout,
+					       "*** %s",
+					       sys_siglist[termination_signal]);
+				SEND_MTOOL_MSG(
+					(void) sprintf(&tmp_buf[strlen(tmp_buf)],
+						       "*** %s",
+						       sys_siglist[termination_signal]);
+				);
+			}
+#endif
+			if (core_dumped) {
+				(void) fprintf(stdout,
+					       catgets(libmksdmsi18n_catd, 1, 107, " - core dumped"));
+				SEND_MTOOL_MSG(
+					(void) sprintf(&tmp_buf[strlen(tmp_buf)],
+						       catgets(libmksdmsi18n_catd, 1, 108, " - core dumped"));
+				);
+			}
+		}
+		if (ignore_error) {
+			(void) fprintf(stdout,
+				       catgets(libmksdmsi18n_catd, 1, 109, " (ignored)"));
+			SEND_MTOOL_MSG(
+				(void) sprintf(&tmp_buf[strlen(tmp_buf)],
+					       catgets(libmksdmsi18n_catd, 1, 110, " (ignored)"));
+			);
+		}
+		(void) fprintf(stdout, "\n");
+		(void) fflush(stdout);
+		SEND_MTOOL_MSG(
+			make_output_msg->appendOutput(AVO_STRDUP(tmp_buf));
+		);
+	}
+	SEND_MTOOL_MSG(
+		xdr_msg = (RWCollectable*) make_output_msg;
+		xdr(xdrs_p, xdr_msg);
+		delete make_output_msg;
+	);
+
+#ifdef PRINT_EXIT_STATUS
+	warning_mksh(NOCATGETS("I'm in await(), returning failed."));
+#endif
+
+	return failed;
+}
+
+/*
+ *	sh_command2string(command, destination)
+ *
+ *	Run one sh command and capture the output from it.
+ *
+ *	Return value:
+ *
+ *	Parameters:
+ *		command		The command to run
+ *		destination	Where to deposit the output from the command
+ *		
+ *	Static variables used:
+ *
+ *	Global variables used:
+ */
+void
+sh_command2string(register String command, register String destination)
+{
+	register FILE		*fd;
+	register int		chr;
+	int			status;
+	Boolean			command_generated_output = false;
+
+	command->text.p = (int) nul_char;
+	WCSTOMBS(mbs_buffer, command->buffer.start);
+	if ((fd = popen(mbs_buffer, "r")) == NULL) {
+		WCSTOMBS(mbs_buffer, command->buffer.start);
+		fatal_mksh(catgets(libmksdmsi18n_catd, 1, 111, "Could not run command `%s' for :sh transformation"),
+		      mbs_buffer);
+	}
+	while ((chr = getc(fd)) != EOF) {
+		if (chr == (int) newline_char) {
+			chr = (int) space_char;
+		}
+		command_generated_output = true;
+		append_char(chr, destination);
+	}
+
+	/*
+	 * We don't want to keep the last LINE_FEED since usually
+	 * the output of the 'sh:' command is used to evaluate
+	 * some MACRO. ( /bin/sh and other shell add a line feed
+	 * to the output so that the prompt appear in the right place.
+	 * We don't need that
+	 */
+	if (command_generated_output){
+		if ( *(destination->text.p-1) == (int) space_char) {
+			* (-- destination->text.p) = '\0';
+		} 
+	} else {
+		/*
+		 * If the command didn't generate any output,
+		 * set the buffer to a null string.
+		 */
+		*(destination->text.p) = '\0';
+	}
+			
+	status = pclose(fd);
+	if (status != 0) {
+		WCSTOMBS(mbs_buffer, command->buffer.start);
+		fatal_mksh(catgets(libmksdmsi18n_catd, 1, 112, "The command `%s' returned status `%d'"),
+		      mbs_buffer,
+		      WEXITSTATUS(status));
+	}
+}
+
+
--- /dev/null	2015-05-20 11:04:21.000000000 -0400
+++ new/usr/src/cmd/make/lib/mksh/src/globals.cc	2015-05-20 11:04:21.533310330 -0400
@@ -0,0 +1,140 @@
+/*
+ * 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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)globals.cc 1.16 06/12/12
+ */
+
+#pragma	ident	"@(#)globals.cc	1.16	06/12/12"
+
+/*
+ *	globals.cc
+ *
+ *	This declares all global variables
+ */
+
+/*
+ * Included files
+ */
+#include <mksh/globals.h>
+
+/*
+ * Defined macros
+ */
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Global variables
+ */
+char		char_semantics[CHAR_SEMANTICS_ENTRIES];
+wchar_t		char_semantics_char[] = {
+	ampersand_char,
+	asterisk_char,
+	at_char,
+	backquote_char,
+	backslash_char,
+	bar_char,
+	bracketleft_char,
+	bracketright_char,
+	colon_char,
+	dollar_char,
+	doublequote_char,
+	equal_char,
+	exclam_char,
+	greater_char,
+	hat_char,
+	hyphen_char,
+	less_char,
+	newline_char,
+	numbersign_char,
+	parenleft_char,
+	parenright_char,
+	percent_char,
+	plus_char,
+	question_char,
+	quote_char,
+	semicolon_char,
+#ifdef SGE_SUPPORT
+	space_char,
+	tab_char,
+#endif
+	nul_char
+};
+Macro_list	cond_macro_list;
+Boolean		conditional_macro_used;
+Boolean		do_not_exec_rule;		/* `-n' */
+Boolean		dollarget_seen;
+Boolean		dollarless_flag;
+Name		dollarless_value;
+Envvar		envvar;
+#ifdef lint
+char		**environ;
+#endif
+#ifdef SUN5_0
+int		exit_status;
+#endif
+wchar_t		*file_being_read;
+/* Variable gnu_style=true if env. var. SUN_MAKE_COMPAT_MODE=GNU (RFE 4866328) */
+Boolean		gnu_style = false;
+Name_set	hashtab;
+Name		host_arch;
+Name		host_mach;
+int		line_number;
+char		*make_state_lockfile;
+Boolean		make_word_mentioned;
+Makefile_type	makefile_type = reading_nothing;
+char		mbs_buffer[(MAXPATHLEN * MB_LEN_MAX)];
+Name		path_name;
+Boolean		posix = true;
+Name		hat;
+Name		query;
+Boolean		query_mentioned;
+Boolean		reading_environment;
+Name		shell_name;
+Boolean		svr4 = false;
+Name		target_arch;
+Name		target_mach;
+Boolean		tilde_rule;
+Name		virtual_root;
+Boolean		vpath_defined;
+Name		vpath_name;
+wchar_t		wcs_buffer[MAXPATHLEN];
+Boolean		working_on_targets;
+#if defined (TEAMWARE_MAKE_CMN) && defined(REDIRECT_ERR)
+Boolean		out_err_same;
+#endif
+pid_t		childPid = -1;	// This variable is used for killing child's process
+				// Such as qrsh, running command, etc.
+
+/*
+ * timestamps defined in defs.h
+ */
+const timestruc_t file_no_time		= { -1, 0 };
+const timestruc_t file_doesnt_exist	= { 0, 0 };
+const timestruc_t file_is_dir		= { 1, 0 };
+const timestruc_t file_min_time		= { 2, 0 };
+const timestruc_t file_max_time		= { INT_MAX, 0 };
--- /dev/null	2015-05-20 11:04:21.000000000 -0400
+++ new/usr/src/cmd/make/lib/mksh/src/i18n.cc	2015-05-20 11:04:21.723530987 -0400
@@ -0,0 +1,100 @@
+/*
+ * 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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)i18n.cc 1.3 06/12/12
+ */
+
+#pragma	ident	"@(#)i18n.cc	1.3	06/12/12"
+
+/*
+ *      i18n.cc
+ *
+ *      Deal with internationalization conversions
+ */
+
+/*
+ * Included files
+ */
+#include <mksh/i18n.h>
+#include <mksh/misc.h>		/* setup_char_semantics() */
+#if defined (linux)
+#	include <wctype.h>
+#	include <wchar.h>
+#	define wschr(x,y) wcschr(x,y)
+#endif
+
+/*
+ *	get_char_semantics_value(ch)
+ *
+ *	Return value:
+ *		The character semantics of ch.
+ *
+ *	Parameters:
+ *		ch		character we want semantics for.
+ *
+ */
+char
+get_char_semantics_value(wchar_t ch)
+{
+	static Boolean	char_semantics_setup;
+
+	if (!char_semantics_setup) {
+		setup_char_semantics();
+		char_semantics_setup = true;
+	}
+	return char_semantics[get_char_semantics_entry(ch)];
+}
+
+/*
+ *	get_char_semantics_entry(ch)
+ *
+ *	Return value:
+ *		The slot number in the array for special make chars,
+ *		else the slot number of the last array entry.
+ *
+ *	Parameters:
+ *		ch		The wide character
+ *
+ *	Global variables used:
+ *		char_semantics_char[]	array of special wchar_t chars
+ *					"&*@`\\|[]:$=!>-\n#()%?;^<'\""
+ */
+int
+get_char_semantics_entry(wchar_t ch)
+{
+	wchar_t		*char_sem_char;
+
+	char_sem_char = (wchar_t *) wschr(char_semantics_char, ch);
+	if (char_sem_char == NULL) {
+		/*
+		 * Return the integer entry for the last slot,
+		 * whose content is empty.
+		 */
+		return (CHAR_SEMANTICS_ENTRIES - 1);
+	} else {
+		return (char_sem_char - char_semantics_char);
+	}
+}
+
--- /dev/null	2015-05-20 11:04:21.000000000 -0400
+++ new/usr/src/cmd/make/lib/mksh/src/libmksh.msg	2015-05-20 11:04:21.913774659 -0400
@@ -0,0 +1,81 @@
+
+$quote "
+
+
+$set	1
+$
+$ 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 1996 Sun Microsystems, Inc. All rights reserved.
+$ Use is subject to license terms.
+$
+$ @(#)libmksh.msg 1.2 06/12/12
+$
+89	"ulimit() failed: %s"
+90	"Couldn't open standard out temp file `%s': %s"
+91	"Couldn't open standard error temp file `%s': %s"
+92	"Could not load `/usr/bin/nice': %s"
+93	"Could not load Shell from `%s': %s"
+94	"fork failed: %s"
+95	"Command `%s' has more than %d arguments"
+96	"Cannot load command `%s': %s"
+97	"fork failed: %s"
+98	"wait() failed: %s"
+99	"Could not open filter file for -X"
+100	"Could not stat filter file for -X"
+101	"\n**** Error: Directory %s Target %s:\n%s\n"
+102	"**** Error: Directory %s Target %s\n"
+103	"*** Error code %d"
+104	"*** Error code %d"
+105	"*** Signal %d"
+106	"*** Signal %d"
+107	" - core dumped"
+108	" - core dumped"
+109	" (ignored)"
+110	" (ignored)"
+111	"Could not run command `%s' for :sh transformation"
+112	"The command `%s' returned status `%d'"
+113	"Loop detected when expanding macro value `%s'"
+114	"'$' at end of string `%s'"
+115	"'$' at end of line"
+116	"Unmatched `%c' in string `%s'"
+117	"Premature EOF"
+118	"Unmatched `%c' on line"
+119	"Illegal macro reference `%s'"
+120	"= missing from replacement macro reference"
+121	"= missing from replacement macro reference"
+122	"%% missing from replacement macro reference"
+123	"%% missing from replacement macro reference"
+124	"Too many %% in pattern"
+125	"Conditional macro `%s' referenced on line %d"
+126	"Out of memory"
+127	"Error %d"
+128	"mksh: Fatal error: "
+129	"Current working directory %s\n"
+131	"mksh: Fatal error in reader: "
+133	"Current working directory %s\n"
+134	"mksh: Warning: "
+135	"Current working directory %s\n"
+136	"Internal error. Unknown prop type %d"
+137	"`cd %s' failed, and conversion of %s to automounter pathname also failed"
+138	"`cd %s' and `cd %s' both failed"
+139	"The following command caused the error:\n%s\n"
+140	"Error reading `%s': Premature EOF"
+141	"Error reading `%s': %s"
--- /dev/null	2015-05-20 11:04:22.000000000 -0400
+++ new/usr/src/cmd/make/lib/mksh/src/macro.cc	2015-05-20 11:04:22.251741006 -0400
@@ -0,0 +1,1414 @@
+/*
+ * 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.
+ */
+/*
+ * @(#)macro.cc 1.22 06/12/12
+ */
+
+#pragma	ident	"@(#)macro.cc	1.22	06/12/12"
+
+/*
+ *	macro.cc
+ *
+ *	Handle expansion of make macros
+ */
+
+/*
+ * Included files
+ */
+#include <mksh/dosys.h>		/* sh_command2string() */
+#include <mksh/i18n.h>		/* get_char_semantics_value() */
+#include <mksh/macro.h>
+#include <mksh/misc.h>		/* retmem() */
+#include <mksh/read.h>		/* get_next_block_fn() */
+#include <mksdmsi18n/mksdmsi18n.h>	/* libmksdmsi18n_init() */
+
+/*
+ * File table of contents
+ */
+static void	add_macro_to_global_list(Name macro_to_add);
+#ifdef NSE
+static void	expand_value_with_daemon(Name name, register Property macro, register String destination, Boolean cmd);
+#else
+static void	expand_value_with_daemon(Name, register Property macro, register String destination, Boolean cmd);
+#endif
+
+static void	init_arch_macros(void);
+static void	init_mach_macros(void);
+static Boolean	init_arch_done = false;
+static Boolean	init_mach_done = false;
+
+
+long env_alloc_num = 0;
+long env_alloc_bytes = 0;
+
+/*
+ *	getvar(name)
+ *
+ *	Return expanded value of macro.
+ *
+ *	Return value:
+ *				The expanded value of the macro
+ *
+ *	Parameters:
+ *		name		The name of the macro we want the value for
+ *
+ *	Global variables used:
+ */
+Name
+getvar(register Name name)
+{
+	String_rec		destination;
+	wchar_t			buffer[STRING_BUFFER_LENGTH];
+	register Name		result;
+
+	if ((name == host_arch) || (name == target_arch)) {
+		if (!init_arch_done) {
+			init_arch_done = true;
+			init_arch_macros();
+		}
+	}
+	if ((name == host_mach) || (name == target_mach)) {
+		if (!init_mach_done) {
+			init_mach_done = true;
+			init_mach_macros();
+		}
+	}
+
+	INIT_STRING_FROM_STACK(destination, buffer);
+	expand_value(maybe_append_prop(name, macro_prop)->body.macro.value,
+		     &destination,
+		     false);
+	result = GETNAME(destination.buffer.start, FIND_LENGTH);
+	if (destination.free_after_use) {
+		retmem(destination.buffer.start);
+	}
+	return result;
+}
+
+/*
+ *	expand_value(value, destination, cmd)
+ *
+ *	Recursively expands all macros in the string value.
+ *	destination is where the expanded value should be appended.
+ *
+ *	Parameters:
+ *		value		The value we are expanding
+ *		destination	Where to deposit the expansion
+ *		cmd		If we are evaluating a command line we
+ *				turn \ quoting off
+ *
+ *	Global variables used:
+ */
+void
+expand_value(Name value, register String destination, Boolean cmd)
+{
+	Source_rec		sourceb;
+	register Source		source = &sourceb;
+	register wchar_t	*source_p = NULL;
+	register wchar_t	*source_end = NULL;
+	wchar_t			*block_start = NULL;
+	int			quote_seen = 0;
+
+	if (value == NULL) {
+		/*
+		 * Make sure to get a string allocated even if it
+		 * will be empty.
+		 */
+		MBSTOWCS(wcs_buffer, "");
+		append_string(wcs_buffer, destination, FIND_LENGTH);
+		destination->text.end = destination->text.p;
+		return;
+	}
+	if (!value->dollar) {
+		/*
+		 * If the value we are expanding does not contain
+		 * any $, we don't have to parse it.
+		 */
+		APPEND_NAME(value,
+			destination,
+			(int) value->hash.length
+		);
+		destination->text.end = destination->text.p;
+		return;
+	}
+
+	if (value->being_expanded) {
+		fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 113, "Loop detected when expanding macro value `%s'"),
+			     value->string_mb);
+	}
+	value->being_expanded = true;
+	/* Setup the structure we read from */
+	Wstring vals(value);
+	sourceb.string.text.p = sourceb.string.buffer.start = wsdup(vals.get_string());
+	sourceb.string.free_after_use = true;
+	sourceb.string.text.end =
+	  sourceb.string.buffer.end =
+	    sourceb.string.text.p + value->hash.length;
+	sourceb.previous = NULL;
+	sourceb.fd = -1;
+	sourceb.inp_buf =
+	  sourceb.inp_buf_ptr =
+	    sourceb.inp_buf_end = NULL;
+	sourceb.error_converting = false;
+	/* Lift some pointers from the struct to local register variables */
+	CACHE_SOURCE(0);
+/* We parse the string in segments */
+/* We read chars until we find a $, then we append what we have read so far */
+/* (since last $ processing) to the destination. When we find a $ we call */
+/* expand_macro() and let it expand that particular $ reference into dest */
+	block_start = source_p;
+	quote_seen = 0;
+	for (; 1; source_p++) {
+		switch (GET_CHAR()) {
+		case backslash_char:
+			/* Quote $ in macro value */
+			if (!cmd) {
+				quote_seen = ~quote_seen;
+			}
+			continue;
+		case dollar_char:
+			/* Save the plain string we found since */
+			/* start of string or previous $ */
+			if (quote_seen) {
+				append_string(block_start,
+					      destination,
+					      source_p - block_start - 1);
+				block_start = source_p;
+				break;
+			}
+			append_string(block_start,
+				      destination,
+				      source_p - block_start);
+			source->string.text.p = ++source_p;
+			UNCACHE_SOURCE();
+			/* Go expand the macro reference */
+			expand_macro(source, destination, sourceb.string.buffer.start, cmd);
+			CACHE_SOURCE(1);
+			block_start = source_p + 1;
+			break;
+		case nul_char:
+			/* The string ran out. Get some more */
+			append_string(block_start,
+				      destination,
+				      source_p - block_start);
+			GET_NEXT_BLOCK_NOCHK(source);
+			if (source == NULL) {
+				destination->text.end = destination->text.p;
+				value->being_expanded = false;
+				return;
+			}
+			if (source->error_converting) {
+				fatal_reader_mksh(NOCATGETS("Internal error: Invalid byte sequence in expand_value()"));
+			}
+			block_start = source_p;
+			source_p--;
+			continue;
+		}
+		quote_seen = 0;
+	}
+	retmem(sourceb.string.buffer.start);
+}
+
+/*
+ *	expand_macro(source, destination, current_string, cmd)
+ *
+ *	Should be called with source->string.text.p pointing to
+ *	the first char after the $ that starts a macro reference.
+ *	source->string.text.p is returned pointing to the first char after
+ *	the macro name.
+ *	It will read the macro name, expanding any macros in it,
+ *	and get the value. The value is then expanded.
+ *	destination is a String that is filled in with the expanded macro.
+ *	It may be passed in referencing a buffer to expand the macro into.
+ * 	Note that most expansions are done on demand, e.g. right 
+ *	before the command is executed and not while the file is
+ * 	being parsed.
+ *
+ *	Parameters:
+ *		source		The source block that references the string
+ *				to expand
+ *		destination	Where to put the result
+ *		current_string	The string we are expanding, for error msg
+ *		cmd		If we are evaluating a command line we
+ *				turn \ quoting off
+ *
+ *	Global variables used:
+ *		funny		Vector of semantic tags for characters
+ *		is_conditional	Set if a conditional macro is refd
+ *		make_word_mentioned Set if the word "MAKE" is mentioned
+ *		makefile_type	We deliver extra msg when reading makefiles
+ *		query		The Name "?", compared against
+ *		query_mentioned	Set if the word "?" is mentioned
+ */
+void
+expand_macro(register Source source, register String destination, wchar_t *current_string, Boolean cmd)
+{
+	static Name		make = (Name)NULL;
+	static wchar_t		colon_sh[4];
+	static wchar_t		colon_shell[7];
+	String_rec		string;
+	wchar_t			buffer[STRING_BUFFER_LENGTH];
+	register wchar_t	*source_p = source->string.text.p;
+	register wchar_t	*source_end = source->string.text.end;
+	register int		closer = 0;
+	wchar_t			*block_start = (wchar_t *)NULL;
+	int			quote_seen = 0;
+	register int		closer_level = 1;
+	Name			name = (Name)NULL;
+	wchar_t			*colon = (wchar_t *)NULL;
+	wchar_t			*percent = (wchar_t *)NULL;
+	wchar_t			*eq = (wchar_t *) NULL;
+	Property		macro = NULL;
+	wchar_t			*p = (wchar_t*)NULL;
+	String_rec		extracted;
+	wchar_t			extracted_string[MAXPATHLEN];
+	wchar_t			*left_head = NULL;
+	wchar_t			*left_tail = NULL;
+	wchar_t			*right_tail = NULL;
+	int			left_head_len = 0;
+	int			left_tail_len = 0;
+	int			tmp_len = 0;
+	wchar_t			*right_hand[128];
+	int			i = 0;
+	enum {
+		no_extract,
+		dir_extract,
+		file_extract
+	}                       extraction = no_extract;
+	enum {
+		no_replace,
+		suffix_replace,
+		pattern_replace,
+		sh_replace
+	}			replacement = no_replace;
+
+	if (make == NULL) {
+		MBSTOWCS(wcs_buffer, NOCATGETS("MAKE"));
+		make = GETNAME(wcs_buffer, FIND_LENGTH);
+
+		MBSTOWCS(colon_sh, NOCATGETS(":sh"));
+		MBSTOWCS(colon_shell, NOCATGETS(":shell"));
+	}
+
+	right_hand[0] = NULL;
+
+	/* First copy the (macro-expanded) macro name into string. */
+	INIT_STRING_FROM_STACK(string, buffer);
+recheck_first_char:
+	/* Check the first char of the macro name to figure out what to do. */
+	switch (GET_CHAR()) {
+	case nul_char:
+		GET_NEXT_BLOCK_NOCHK(source);
+		if (source == NULL) {
+			WCSTOMBS(mbs_buffer, current_string);
+			fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 114, "'$' at end of string `%s'"),
+				     mbs_buffer);
+		}
+		if (source->error_converting) {
+			fatal_reader_mksh(NOCATGETS("Internal error: Invalid byte sequence in expand_macro()"));
+		}
+		goto recheck_first_char;
+	case parenleft_char:
+		/* Multi char name. */
+		closer = (int) parenright_char;
+		break;
+	case braceleft_char:
+		/* Multi char name. */
+		closer = (int) braceright_char;
+		break;
+	case newline_char:
+		fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 115, "'$' at end of line"));
+	default:
+		/* Single char macro name. Just suck it up */
+		append_char(*source_p, &string);
+		source->string.text.p = source_p + 1;
+		goto get_macro_value;
+	}
+
+	/* Handle multi-char macro names */
+	block_start = ++source_p;
+	quote_seen = 0;
+	for (; 1; source_p++) {
+		switch (GET_CHAR()) {
+		case nul_char:
+			append_string(block_start,
+				      &string,
+				      source_p - block_start);
+			GET_NEXT_BLOCK_NOCHK(source);
+			if (source == NULL) {
+				if (current_string != NULL) {
+					WCSTOMBS(mbs_buffer, current_string);
+					fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 116, "Unmatched `%c' in string `%s'"),
+						     closer ==
+						     (int) braceright_char ?
+						     (int) braceleft_char :
+						     (int) parenleft_char,
+						     mbs_buffer);
+				} else {
+					fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 117, "Premature EOF"));
+				}
+			}
+			if (source->error_converting) {
+				fatal_reader_mksh(NOCATGETS("Internal error: Invalid byte sequence in expand_macro()"));
+			}
+			block_start = source_p;
+			source_p--;
+			continue;
+		case newline_char:
+			fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 118, "Unmatched `%c' on line"),
+				     closer == (int) braceright_char ?
+				     (int) braceleft_char :
+				     (int) parenleft_char);
+		case backslash_char:
+			/* Quote dollar in macro value. */
+			if (!cmd) {
+				quote_seen = ~quote_seen;
+			}
+			continue;
+		case dollar_char:
+			/*
+			 * Macro names may reference macros.
+			 * This expands the value of such macros into the
+			 * macro name string.
+			 */
+			if (quote_seen) {
+				append_string(block_start,
+					      &string,
+					      source_p - block_start - 1);
+				block_start = source_p;
+				break;
+			}
+			append_string(block_start,
+				      &string,
+				      source_p - block_start);
+			source->string.text.p = ++source_p;
+			UNCACHE_SOURCE();
+			expand_macro(source, &string, current_string, cmd);
+			CACHE_SOURCE(0);
+			block_start = source_p;
+			source_p--;
+			break;
+		case parenleft_char:
+			/* Allow nested pairs of () in the macro name. */
+			if (closer == (int) parenright_char) {
+				closer_level++;
+			}
+			break;
+		case braceleft_char:
+			/* Allow nested pairs of {} in the macro name. */
+			if (closer == (int) braceright_char) {
+				closer_level++;
+			}
+			break;
+		case parenright_char:
+		case braceright_char:
+			/*
+			 * End of the name. Save the string in the macro
+			 * name string.
+			 */
+			if ((*source_p == closer) && (--closer_level <= 0)) {
+				source->string.text.p = source_p + 1;
+				append_string(block_start,
+					      &string,
+					      source_p - block_start);
+				goto get_macro_value;
+			}
+			break;
+		}
+		quote_seen = 0;
+	}
+	/*
+	 * We got the macro name. We now inspect it to see if it
+	 * specifies any translations of the value.
+	 */
+get_macro_value:
+	name = NULL;
+	/* First check if we have a $(@D) type translation. */
+	if ((get_char_semantics_value(string.buffer.start[0]) &
+	     (int) special_macro_sem) &&
+	    (string.text.p - string.buffer.start >= 2) &&
+	    ((string.buffer.start[1] == 'D') ||
+	     (string.buffer.start[1] == 'F'))) {
+		switch (string.buffer.start[1]) {
+		case 'D':
+			extraction = dir_extract;
+			break;
+		case 'F':
+			extraction = file_extract;
+			break;
+		default:
+			WCSTOMBS(mbs_buffer, string.buffer.start);
+			fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 119, "Illegal macro reference `%s'"),
+				     mbs_buffer);
+		}
+		/* Internalize the macro name using the first char only. */
+		name = GETNAME(string.buffer.start, 1);
+		(void) wscpy(string.buffer.start, string.buffer.start + 2);
+	}
+	/* Check for other kinds of translations. */
+	if ((colon = (wchar_t *) wschr(string.buffer.start,
+				       (int) colon_char)) != NULL) {
+		/*
+		 * We have a $(FOO:.c=.o) type translation.
+		 * Get the name of the macro proper.
+		 */
+		if (name == NULL) {
+			name = GETNAME(string.buffer.start,
+				       colon - string.buffer.start);
+		}
+		/* Pickup all the translations. */
+		if (IS_WEQUAL(colon, colon_sh) || IS_WEQUAL(colon, colon_shell)) {
+			replacement = sh_replace;
+		} else if ((svr4) ||
+		           ((percent = (wchar_t *) wschr(colon + 1,
+							 (int) percent_char)) == NULL)) {
+			while (colon != NULL) {
+				if ((eq = (wchar_t *) wschr(colon + 1,
+							    (int) equal_char)) == NULL) {
+					fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 120, "= missing from replacement macro reference"));
+				}
+				left_tail_len = eq - colon - 1;
+				if(left_tail) {
+					retmem(left_tail);
+				}
+				left_tail = ALLOC_WC(left_tail_len + 1);
+				(void) wsncpy(left_tail,
+					      colon + 1,
+					      eq - colon - 1);
+				left_tail[eq - colon - 1] = (int) nul_char;
+				replacement = suffix_replace;
+				if ((colon = (wchar_t *) wschr(eq + 1,
+							       (int) colon_char)) != NULL) {
+					tmp_len = colon - eq;
+					if(right_tail) {
+						retmem(right_tail);
+					}
+					right_tail = ALLOC_WC(tmp_len);
+					(void) wsncpy(right_tail,
+						      eq + 1,
+						      colon - eq - 1);
+					right_tail[colon - eq - 1] =
+					  (int) nul_char;
+				} else {
+					if(right_tail) {
+						retmem(right_tail);
+					}
+					right_tail = ALLOC_WC(wslen(eq) + 1);
+					(void) wscpy(right_tail, eq + 1);
+				}
+			}
+		} else {
+			if ((eq = (wchar_t *) wschr(colon + 1,
+						    (int) equal_char)) == NULL) {
+				fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 121, "= missing from replacement macro reference"));
+			}
+			if ((percent = (wchar_t *) wschr(colon + 1,
+							 (int) percent_char)) == NULL) {
+				fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 122, "%% missing from replacement macro reference"));
+			}
+			if (eq < percent) {
+				fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 123, "%% missing from replacement macro reference"));
+			}
+
+			if (percent > (colon + 1)) {
+				tmp_len = percent - colon;
+				if(left_head) {
+					retmem(left_head);
+				}
+				left_head = ALLOC_WC(tmp_len);
+				(void) wsncpy(left_head,
+					      colon + 1,
+					      percent - colon - 1);
+				left_head[percent-colon-1] = (int) nul_char;
+				left_head_len = percent-colon-1;
+			} else {
+				left_head = NULL;
+				left_head_len = 0;
+			}
+
+			if (eq > percent+1) {
+				tmp_len = eq - percent;
+				if(left_tail) {
+					retmem(left_tail);
+				}
+				left_tail = ALLOC_WC(tmp_len);
+				(void) wsncpy(left_tail,
+					      percent + 1,
+					      eq - percent - 1);
+				left_tail[eq-percent-1] = (int) nul_char;
+				left_tail_len = eq-percent-1;
+			} else {
+				left_tail = NULL;
+				left_tail_len = 0;
+			}
+
+			if ((percent = (wchar_t *) wschr(++eq,
+							 (int) percent_char)) == NULL) {
+
+				right_hand[0] = ALLOC_WC(wslen(eq) + 1);
+				right_hand[1] = NULL;
+				(void) wscpy(right_hand[0], eq);
+			} else {
+				i = 0;
+				do {
+					right_hand[i] = ALLOC_WC(percent-eq+1);
+					(void) wsncpy(right_hand[i],
+						      eq,
+						      percent - eq);
+					right_hand[i][percent-eq] =
+					  (int) nul_char;
+					if (i++ >= VSIZEOF(right_hand)) {
+						fatal_mksh(catgets(libmksdmsi18n_catd, 1, 124, "Too many %% in pattern"));
+					}
+					eq = percent + 1;
+					if (eq[0] == (int) nul_char) {
+						MBSTOWCS(wcs_buffer, "");
+						right_hand[i] = (wchar_t *) wsdup(wcs_buffer);
+						i++;
+						break;
+					}
+				} while ((percent = (wchar_t *) wschr(eq, (int) percent_char)) != NULL);
+				if (eq[0] != (int) nul_char) {
+					right_hand[i] = ALLOC_WC(wslen(eq) + 1);
+					(void) wscpy(right_hand[i], eq);
+					i++;
+				}
+				right_hand[i] = NULL;
+			}
+			replacement = pattern_replace;
+		}
+	}
+	if (name == NULL) {
+		/*
+		 * No translations found.
+		 * Use the whole string as the macro name.
+		 */
+		name = GETNAME(string.buffer.start,
+			       string.text.p - string.buffer.start);
+	}
+	if (string.free_after_use) {
+		retmem(string.buffer.start);
+	}
+	if (name == make) {
+		make_word_mentioned = true;
+	}
+	if (name == query) {
+		query_mentioned = true;
+	}
+	if ((name == host_arch) || (name == target_arch)) {
+		if (!init_arch_done) {
+			init_arch_done = true;
+			init_arch_macros();
+		}
+	}
+	if ((name == host_mach) || (name == target_mach)) {
+		if (!init_mach_done) {
+			init_mach_done = true;
+			init_mach_macros();
+		}
+	}
+	/* Get the macro value. */
+	macro = get_prop(name->prop, macro_prop);
+#ifdef NSE
+        if (nse_watch_vars && nse && macro != NULL) {
+                if (macro->body.macro.imported) {
+                        nse_shell_var_used= name;
+		}
+                if (macro->body.macro.value != NULL){
+	              if (nse_backquotes(macro->body.macro.value->string)) {
+	                       nse_backquote_seen= name;
+		      }
+	       }
+	}
+#endif
+	if ((macro != NULL) && macro->body.macro.is_conditional) {
+		conditional_macro_used = true;
+		/*
+		 * Add this conditional macro to the beginning of the
+		 * global list.
+		 */
+		add_macro_to_global_list(name);
+		if (makefile_type == reading_makefile) {
+			warning_mksh(catgets(libmksdmsi18n_catd, 1, 164, "Conditional macro `%s' referenced in file `%ws', line %d"),
+					name->string_mb, file_being_read, line_number);
+		}
+	}
+	/* Macro name read and parsed. Expand the value. */
+	if ((macro == NULL) || (macro->body.macro.value == NULL)) {
+		/* If the value is empty, we just get out of here. */
+		goto exit;
+	}
+	if (replacement == sh_replace) {
+		/* If we should do a :sh transform, we expand the command
+		 * and process it.
+		 */
+		INIT_STRING_FROM_STACK(string, buffer);
+		/* Expand the value into a local string buffer and run cmd. */
+		expand_value_with_daemon(name, macro, &string, cmd);
+		sh_command2string(&string, destination);
+	} else if ((replacement != no_replace) || (extraction != no_extract)) {
+		/*
+		 * If there were any transforms specified in the macro
+		 * name, we deal with them here.
+		 */
+		INIT_STRING_FROM_STACK(string, buffer);
+		/* Expand the value into a local string buffer. */
+		expand_value_with_daemon(name, macro, &string, cmd);
+		/* Scan the expanded string. */
+		p = string.buffer.start;
+		while (*p != (int) nul_char) {
+			wchar_t		chr;
+
+			/*
+			 * First skip over any white space and append
+			 * that to the destination string.
+			 */
+			block_start = p;
+			while ((*p != (int) nul_char) && iswspace(*p)) {
+				p++;
+			}
+			append_string(block_start,
+				      destination,
+				      p - block_start);
+			/* Then find the end of the next word. */
+			block_start = p;
+			while ((*p != (int) nul_char) && !iswspace(*p)) {
+				p++;
+			}
+			/* If we cant find another word we are done */
+			if (block_start == p) {
+				break;
+			}
+			/* Then apply the transforms to the word */
+			INIT_STRING_FROM_STACK(extracted, extracted_string);
+			switch (extraction) {
+			case dir_extract:
+				/*
+				 * $(@D) type transform. Extract the
+				 * path from the word. Deliver "." if
+				 * none is found.
+				 */
+				if (p != NULL) {
+					chr = *p;
+					*p = (int) nul_char;
+				}
+				eq = (wchar_t *) wsrchr(block_start, (int) slash_char);
+				if (p != NULL) {
+					*p = chr;
+				}
+				if ((eq == NULL) || (eq > p)) {
+					MBSTOWCS(wcs_buffer, ".");
+					append_string(wcs_buffer, &extracted, 1);
+				} else {
+					append_string(block_start,
+						      &extracted,
+						      eq - block_start);
+				}
+				break;
+			case file_extract:
+				/*
+				 * $(@F) type transform. Remove the path
+				 * from the word if any.
+				 */
+				if (p != NULL) {
+					chr = *p;
+					*p = (int) nul_char;
+				}
+				eq = (wchar_t *) wsrchr(block_start, (int) slash_char);
+				if (p != NULL) {
+					*p = chr;
+				}
+				if ((eq == NULL) || (eq > p)) {
+					append_string(block_start,
+						      &extracted,
+						      p - block_start);
+				} else {
+					append_string(eq + 1,
+						      &extracted,
+						      p - eq - 1);
+				}
+				break;
+			case no_extract:
+				append_string(block_start,
+					      &extracted,
+					      p - block_start);
+				break;
+			}
+			switch (replacement) {
+			case suffix_replace:
+				/*
+				 * $(FOO:.o=.c) type transform.
+				 * Maybe replace the tail of the word.
+				 */
+				if (((extracted.text.p -
+				      extracted.buffer.start) >=
+				     left_tail_len) &&
+				    IS_WEQUALN(extracted.text.p - left_tail_len,
+					      left_tail,
+					      left_tail_len)) {
+					append_string(extracted.buffer.start,
+						      destination,
+						      (extracted.text.p -
+						       extracted.buffer.start)
+						      - left_tail_len);
+					append_string(right_tail,
+						      destination,
+						      FIND_LENGTH);
+				} else {
+					append_string(extracted.buffer.start,
+						      destination,
+						      FIND_LENGTH);
+				}
+				break;
+			case pattern_replace:
+				/* $(X:a%b=c%d) type transform. */
+				if (((extracted.text.p -
+				      extracted.buffer.start) >=
+				     left_head_len+left_tail_len) &&
+				    IS_WEQUALN(left_head,
+					      extracted.buffer.start,
+					      left_head_len) &&
+				    IS_WEQUALN(left_tail,
+					      extracted.text.p - left_tail_len,
+					      left_tail_len)) {
+					i = 0;
+					while (right_hand[i] != NULL) {
+						append_string(right_hand[i],
+							      destination,
+							      FIND_LENGTH);
+						i++;
+						if (right_hand[i] != NULL) {
+							append_string(extracted.buffer.
+								      start +
+								      left_head_len,
+								      destination,
+								      (extracted.text.p - extracted.buffer.start)-left_head_len-left_tail_len);
+						}
+					}
+				} else {
+					append_string(extracted.buffer.start,
+						      destination,
+						      FIND_LENGTH);
+				}
+				break;
+			case no_replace:
+				append_string(extracted.buffer.start,
+					      destination,
+					      FIND_LENGTH);
+				break;
+			case sh_replace:
+				break;
+			    }
+		}
+		if (string.free_after_use) {
+			retmem(string.buffer.start);
+		}
+	} else {
+		/*
+		 * This is for the case when the macro name did not
+		 * specify transforms.
+		 */
+		if (!strncmp(name->string_mb, NOCATGETS("GET"), 3)) {
+			dollarget_seen = true;
+		}
+		dollarless_flag = false;
+		if (!strncmp(name->string_mb, "<", 1) &&
+		    dollarget_seen) {
+			dollarless_flag = true;
+			dollarget_seen = false;
+		}
+		expand_value_with_daemon(name, macro, destination, cmd);
+	}
+exit:
+	if(left_tail) {
+		retmem(left_tail);
+	}
+	if(right_tail) {
+		retmem(right_tail);
+	}
+	if(left_head) {
+		retmem(left_head);
+	}
+	i = 0;
+	while (right_hand[i] != NULL) {
+		retmem(right_hand[i]);
+		i++;
+	}
+	*destination->text.p = (int) nul_char;
+	destination->text.end = destination->text.p;
+}
+
+static void
+add_macro_to_global_list(Name macro_to_add)
+{
+	Macro_list	new_macro;
+	Macro_list	macro_on_list;
+	char		*name_on_list = (char*)NULL;
+	char		*name_to_add = macro_to_add->string_mb;
+	char		*value_on_list = (char*)NULL;
+	char		*value_to_add = (char*)NULL;
+
+	if (macro_to_add->prop->body.macro.value != NULL) {
+		value_to_add = macro_to_add->prop->body.macro.value->string_mb;
+	} else {
+		value_to_add = "";
+	}
+
+	/* 
+	 * Check if this macro is already on list, if so, do nothing
+	 */
+	for (macro_on_list = cond_macro_list;
+	     macro_on_list != NULL;
+	     macro_on_list = macro_on_list->next) {
+
+		name_on_list = macro_on_list->macro_name;
+		value_on_list = macro_on_list->value;
+
+		if (IS_EQUAL(name_on_list, name_to_add)) {
+			if (IS_EQUAL(value_on_list, value_to_add)) {
+				return;
+			}
+		}
+	}
+	new_macro = (Macro_list) malloc(sizeof(Macro_list_rec));
+	new_macro->macro_name = strdup(name_to_add);
+	new_macro->value = strdup(value_to_add);
+	new_macro->next = cond_macro_list;
+	cond_macro_list = new_macro;
+}
+
+/*
+ *	init_arch_macros(void)
+ *
+ *	Set the magic macros TARGET_ARCH, HOST_ARCH,
+ *
+ *	Parameters: 
+ *
+ *	Global variables used:
+ * 	                        host_arch   Property for magic macro HOST_ARCH
+ * 	                        target_arch Property for magic macro TARGET_ARCH
+ *
+ *	Return value:
+ *				The function does not return a value, but can
+ *				call fatal() in case of error.
+ */
+static void
+init_arch_macros(void)
+{
+	String_rec	result_string;
+	wchar_t		wc_buf[STRING_BUFFER_LENGTH];
+	char		mb_buf[STRING_BUFFER_LENGTH];
+	FILE		*pipe;
+	Name		value;
+	int		set_host, set_target;
+#ifdef NSE
+	Property	macro;
+#endif
+#if defined(linux)
+	const char	*mach_command = NOCATGETS("/bin/uname -p");
+#else
+	const char	*mach_command = NOCATGETS("/bin/mach");
+#endif
+
+	set_host = (get_prop(host_arch->prop, macro_prop) == NULL);
+	set_target = (get_prop(target_arch->prop, macro_prop) == NULL);
+
+	if (set_host || set_target) {
+		INIT_STRING_FROM_STACK(result_string, wc_buf);
+		append_char((int) hyphen_char, &result_string);
+
+		if ((pipe = popen(mach_command, "r")) == NULL) {
+			fatal_mksh(catgets(libmksdmsi18n_catd, 1, 185, "Execute of %s failed"), mach_command);
+		}
+		while (fgets(mb_buf, sizeof(mb_buf), pipe) != NULL) {
+			MBSTOWCS(wcs_buffer, mb_buf);
+			append_string(wcs_buffer, &result_string, wslen(wcs_buffer));
+		}
+		if (pclose(pipe) != 0) {
+			fatal_mksh(catgets(libmksdmsi18n_catd, 1, 186, "Execute of %s failed"), mach_command);
+		}
+
+		value = GETNAME(result_string.buffer.start, wslen(result_string.buffer.start));
+
+#ifdef NSE
+	        macro = setvar_daemon(host_arch, value, false, no_daemon, true, 0);
+	        macro->body.macro.imported= true;
+	        macro = setvar_daemon(target_arch, value, false, no_daemon, true, 0);
+	        macro->body.macro.imported= true;
+#else
+		if (set_host) {
+			(void) setvar_daemon(host_arch, value, false, no_daemon, true, 0);
+		}
+		if (set_target) {
+			(void) setvar_daemon(target_arch, value, false, no_daemon, true, 0);
+		}
+#endif
+	}
+}
+
+/*
+ *	init_mach_macros(void)
+ *
+ *	Set the magic macros TARGET_MACH, HOST_MACH,
+ *
+ *	Parameters: 
+ *
+ *	Global variables used:
+ * 	                        host_mach   Property for magic macro HOST_MACH
+ * 	                        target_mach Property for magic macro TARGET_MACH
+ *
+ *	Return value:
+ *				The function does not return a value, but can
+ *				call fatal() in case of error.
+ */
+static void
+init_mach_macros(void)
+{
+	String_rec	result_string;
+	wchar_t		wc_buf[STRING_BUFFER_LENGTH];
+	char		mb_buf[STRING_BUFFER_LENGTH];
+	FILE		*pipe;
+	Name		value;
+	int		set_host, set_target;
+	const char	*arch_command = NOCATGETS("/bin/arch");
+
+	set_host = (get_prop(host_mach->prop, macro_prop) == NULL);
+	set_target = (get_prop(target_mach->prop, macro_prop) == NULL);
+
+	if (set_host || set_target) {
+		INIT_STRING_FROM_STACK(result_string, wc_buf);
+		append_char((int) hyphen_char, &result_string);
+
+		if ((pipe = popen(arch_command, "r")) == NULL) {
+			fatal_mksh(catgets(libmksdmsi18n_catd, 1, 183, "Execute of %s failed"), arch_command);
+		}
+		while (fgets(mb_buf, sizeof(mb_buf), pipe) != NULL) {
+			MBSTOWCS(wcs_buffer, mb_buf);
+			append_string(wcs_buffer, &result_string, wslen(wcs_buffer));
+		}
+		if (pclose(pipe) != 0) {
+			fatal_mksh(catgets(libmksdmsi18n_catd, 1, 184, "Execute of %s failed"), arch_command);
+		}
+
+		value = GETNAME(result_string.buffer.start, wslen(result_string.buffer.start));
+
+		if (set_host) {
+			(void) setvar_daemon(host_mach, value, false, no_daemon, true, 0);
+		}
+		if (set_target) {
+			(void) setvar_daemon(target_mach, value, false, no_daemon, true, 0);
+		}
+	}
+}
+
+/*
+ *	expand_value_with_daemon(name, macro, destination, cmd)
+ *
+ *	Checks for daemons and then maybe calls expand_value().
+ *
+ *	Parameters:
+ *              name            Name of the macro  (Added by the NSE)
+ *		macro		The property block with the value to expand
+ *		destination	Where the result should be deposited
+ *		cmd		If we are evaluating a command line we
+ *				turn \ quoting off
+ *
+ *	Global variables used:
+ */
+static void
+#ifdef NSE
+expand_value_with_daemon(Name name, register Property macro, register String destination, Boolean cmd)
+#else
+expand_value_with_daemon(Name, register Property macro, register String destination, Boolean cmd)
+#endif
+{
+	register Chain		chain;
+
+#ifdef NSE
+        if (reading_dependencies) {
+                /*
+                 * Processing the dependencies themselves
+                 */
+                depvar_dep_macro_used(name);
+	} else {
+                /*
+	         * Processing the rules for the targets
+	         * the nse_watch_vars flags chokes off most
+	         * checks.  it is true only when processing
+	         * the output from a recursive make run
+	         * which is all we are interested in here.
+	         */
+	         if (nse_watch_vars) {
+	                depvar_rule_macro_used(name);
+		}
+	 }
+#endif
+
+	switch (macro->body.macro.daemon) {
+	case no_daemon:
+		if (!svr4 && !posix) {
+			expand_value(macro->body.macro.value, destination, cmd);
+		} else {
+			if (dollarless_flag && tilde_rule) {
+				expand_value(dollarless_value, destination, cmd);
+				dollarless_flag = false;
+				tilde_rule = false;
+			} else {
+				expand_value(macro->body.macro.value, destination, cmd);
+			}
+		}
+		return;
+	case chain_daemon:
+		/* If this is a $? value we call the daemon to translate the */
+		/* list of names to a string */
+		for (chain = (Chain) macro->body.macro.value;
+		     chain != NULL;
+		     chain = chain->next) {
+			APPEND_NAME(chain->name,
+				      destination,
+				      (int) chain->name->hash.length);
+			if (chain->next != NULL) {
+				append_char((int) space_char, destination);
+			}
+		}
+		return;
+	}
+}
+
+/*
+ * We use a permanent buffer to reset SUNPRO_DEPENDENCIES value.
+ */
+char	*sunpro_dependencies_buf = NULL;
+char	*sunpro_dependencies_oldbuf = NULL;
+int	sunpro_dependencies_buf_size = 0;
+
+/*
+ *	setvar_daemon(name, value, append, daemon, strip_trailing_spaces)
+ *
+ *	Set a macro value, possibly supplying a daemon to be used
+ *	when referencing the value.
+ *
+ *	Return value:
+ *				The property block with the new value
+ *
+ *	Parameters:
+ *		name		Name of the macro to set
+ *		value		The value to set
+ *		append		Should we reset or append to the current value?
+ *		daemon		Special treatment when reading the value
+ *		strip_trailing_spaces from the end of value->string
+ *		debug_level	Indicates how much tracing we should do
+ *
+ *	Global variables used:
+ *		makefile_type	Used to check if we should enforce read only
+ *		path_name	The Name "PATH", compared against
+ *		virtual_root	The Name "VIRTUAL_ROOT", compared against
+ *		vpath_defined	Set if the macro VPATH is set
+ *		vpath_name	The Name "VPATH", compared against
+ *		envvar		A list of environment vars with $ in value
+ */
+Property
+setvar_daemon(register Name name, register Name value, Boolean append, Daemon daemon, Boolean strip_trailing_spaces, short debug_level)
+{
+	register Property	macro = maybe_append_prop(name, macro_prop);
+	register Property	macro_apx = get_prop(name->prop, macro_append_prop);
+	int			length = 0;
+	String_rec		destination;
+	wchar_t			buffer[STRING_BUFFER_LENGTH];
+	register Chain		chain;
+	Name			val;
+	wchar_t			*val_string = (wchar_t*)NULL;
+	Wstring			wcb;
+
+#ifdef NSE
+        macro->body.macro.imported = false;
+#endif
+
+	if ((makefile_type != reading_nothing) &&
+	    macro->body.macro.read_only) {
+		return macro;
+	}
+	/* Strip spaces from the end of the value */
+	if (daemon == no_daemon) {
+		if(value != NULL) {
+			wcb.init(value);
+			length = wcb.length();
+			val_string = wcb.get_string();
+		}
+		if ((length > 0) && iswspace(val_string[length-1])) {
+			INIT_STRING_FROM_STACK(destination, buffer);
+			buffer[0] = 0;
+			append_string(val_string, &destination, length);
+			if (strip_trailing_spaces) {
+				while ((length > 0) &&
+				       iswspace(destination.buffer.start[length-1])) {
+					destination.buffer.start[--length] = 0;
+				}
+			}
+			value = GETNAME(destination.buffer.start, FIND_LENGTH);
+		}
+	}
+		
+	if(macro_apx != NULL) {
+		val = macro_apx->body.macro_appendix.value;
+	} else {
+		val = macro->body.macro.value;
+	}
+
+	if (append) {
+		/*
+		 * If we are appending, we just tack the new value after
+		 * the old one with a space in between.
+		 */
+		INIT_STRING_FROM_STACK(destination, buffer);
+		buffer[0] = 0;
+		if ((macro != NULL) && (val != NULL)) {
+			APPEND_NAME(val,
+				      &destination,
+				      (int) val->hash.length);
+			if (value != NULL) {
+				wcb.init(value);
+				if(wcb.length() > 0) {
+					MBTOWC(wcs_buffer, " ");
+					append_char(wcs_buffer[0], &destination);
+				}
+			}
+		}
+		if (value != NULL) {
+			APPEND_NAME(value,
+				      &destination,
+				      (int) value->hash.length);
+		}
+		value = GETNAME(destination.buffer.start, FIND_LENGTH);
+		wcb.init(value);
+		if (destination.free_after_use) {
+			retmem(destination.buffer.start);
+		}
+	}
+
+	/* Debugging trace */
+	if (debug_level > 1) {
+		if (value != NULL) {
+			switch (daemon) {
+			case chain_daemon:
+				(void) printf("%s =", name->string_mb);
+				for (chain = (Chain) value;
+				     chain != NULL;
+				     chain = chain->next) {
+					(void) printf(" %s", chain->name->string_mb);
+				}
+				(void) printf("\n");
+				break;
+			case no_daemon:
+				(void) printf("%s= %s\n",
+					      name->string_mb,
+					      value->string_mb);
+				break;
+			}
+		} else {
+			(void) printf("%s =\n", name->string_mb);
+		}
+	}
+	/* Set the new values in the macro property block */
+/**/
+	if(macro_apx != NULL) {
+		macro_apx->body.macro_appendix.value = value;
+		INIT_STRING_FROM_STACK(destination, buffer);
+		buffer[0] = 0;
+		if (value != NULL) {
+			APPEND_NAME(value,
+				      &destination,
+				      (int) value->hash.length);
+			if (macro_apx->body.macro_appendix.value_to_append != NULL) {
+				MBTOWC(wcs_buffer, " ");
+				append_char(wcs_buffer[0], &destination);
+			}
+		}
+		if (macro_apx->body.macro_appendix.value_to_append != NULL) {
+			APPEND_NAME(macro_apx->body.macro_appendix.value_to_append,
+				      &destination,
+				      (int) macro_apx->body.macro_appendix.value_to_append->hash.length);
+		}
+		value = GETNAME(destination.buffer.start, FIND_LENGTH);
+		if (destination.free_after_use) {
+			retmem(destination.buffer.start);
+		}
+	}
+/**/
+	macro->body.macro.value = value;
+	macro->body.macro.daemon = daemon;
+	/*
+	 * If the user changes the VIRTUAL_ROOT, we need to flush
+	 * the vroot package cache.
+	 */
+	if (name == path_name) {
+		flush_path_cache();
+	}
+	if (name == virtual_root) {
+		flush_vroot_cache();
+	}
+	/* If this sets the VPATH we remember that */
+	if ((name == vpath_name) &&
+	    (value != NULL) &&
+	    (value->hash.length > 0)) {
+		vpath_defined = true;
+	}
+	/*
+	 * For environment variables we also set the
+	 * environment value each time.
+	 */
+	if (macro->body.macro.exported) {
+		static char	*env;
+
+#ifdef DISTRIBUTED
+		if (!reading_environment && (value != NULL)) {
+#else
+		if (!reading_environment && (value != NULL) && value->dollar) {
+#endif
+			Envvar	p;
+
+			for (p = envvar; p != NULL; p = p->next) {
+				if (p->name == name) {
+					p->value = value;
+					p->already_put = false;
+					goto found_it;
+				}
+			}
+			p = ALLOC(Envvar);
+			p->name = name;
+			p->value = value;
+			p->next = envvar;
+			p->env_string = NULL;
+			p->already_put = false;
+			envvar = p;
+found_it:;
+#ifdef DISTRIBUTED
+		}
+		if (reading_environment || (value == NULL) || !value->dollar) {
+#else
+		} else {
+#endif
+			length = 2 + strlen(name->string_mb);
+			if (value != NULL) {
+				length += strlen(value->string_mb);
+			}
+			Property env_prop = maybe_append_prop(name, env_mem_prop);
+			/*
+			 * We use a permanent buffer to reset SUNPRO_DEPENDENCIES value.
+			 */
+			if (!strncmp(name->string_mb, NOCATGETS("SUNPRO_DEPENDENCIES"), 19)) {
+				if (length >= sunpro_dependencies_buf_size) {
+					sunpro_dependencies_buf_size=length*2;
+					if (sunpro_dependencies_buf_size < 4096)
+						sunpro_dependencies_buf_size = 4096; // Default minimum size
+					if (sunpro_dependencies_buf)
+						sunpro_dependencies_oldbuf = sunpro_dependencies_buf;
+					sunpro_dependencies_buf=getmem(sunpro_dependencies_buf_size);
+				}
+				env = sunpro_dependencies_buf;
+			} else {
+				env = getmem(length);
+			}
+			env_alloc_num++;
+			env_alloc_bytes += length;
+			(void) sprintf(env,
+				       "%s=%s",
+				       name->string_mb,
+				       value == NULL ?
+			                 "" : value->string_mb);
+			(void) putenv(env);
+			env_prop->body.env_mem.value = env;
+			if (sunpro_dependencies_oldbuf) {
+				/* Return old buffer */
+				retmem_mb(sunpro_dependencies_oldbuf);
+				sunpro_dependencies_oldbuf = NULL;
+			}
+		}
+	}
+	if (name == target_arch) {
+		Name		ha = getvar(host_arch);
+		Name		ta = getvar(target_arch);
+		Name		vr = getvar(virtual_root);
+		int		length;
+		wchar_t		*new_value;
+		wchar_t		*old_vr;
+		Boolean		new_value_allocated = false;
+
+		Wstring		ha_str(ha);
+		Wstring		ta_str(ta);
+		Wstring		vr_str(vr);
+
+		wchar_t * wcb_ha = ha_str.get_string();
+		wchar_t * wcb_ta = ta_str.get_string();
+		wchar_t * wcb_vr = vr_str.get_string();
+
+		length = 32 +
+		  wslen(wcb_ha) +
+		    wslen(wcb_ta) +
+		      wslen(wcb_vr);
+		old_vr = wcb_vr;
+		MBSTOWCS(wcs_buffer, NOCATGETS("/usr/arch/"));
+		if (IS_WEQUALN(old_vr,
+			       wcs_buffer,
+			       wslen(wcs_buffer))) {
+			old_vr = (wchar_t *) wschr(old_vr, (int) colon_char) + 1;
+		}
+		if ( (ha == ta) || (wslen(wcb_ta) == 0) ) {
+			new_value = old_vr;
+		} else {
+			new_value = ALLOC_WC(length);
+			new_value_allocated = true;
+			WCSTOMBS(mbs_buffer, old_vr);
+#if !defined(linux)
+			(void) wsprintf(new_value,
+				        NOCATGETS("/usr/arch/%s/%s:%s"),
+				        ha->string_mb + 1,
+				        ta->string_mb + 1,
+				        mbs_buffer);
+#else
+			char * mbs_new_value = (char *)getmem(length);
+			(void) sprintf(mbs_new_value,
+				        NOCATGETS("/usr/arch/%s/%s:%s"),
+				        ha->string_mb + 1,
+				        ta->string_mb + 1,
+				        mbs_buffer);
+			MBSTOWCS(new_value, mbs_new_value);
+			retmem_mb(mbs_new_value);
+#endif
+		}
+		if (new_value[0] != 0) {
+			(void) setvar_daemon(virtual_root,
+					     GETNAME(new_value, FIND_LENGTH),
+					     false,
+					     no_daemon,
+					     true,
+					     debug_level);
+		}
+		if (new_value_allocated) {
+			retmem(new_value);
+		}
+	}
+	return macro;
+}
--- /dev/null	2015-05-20 11:04:22.000000000 -0400
+++ new/usr/src/cmd/make/lib/mksh/src/misc.cc	2015-05-20 11:04:22.646363325 -0400
@@ -0,0 +1,1178 @@
+/*
+ * 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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)misc.cc 1.31 06/12/12
+ */
+
+#pragma	ident	"@(#)misc.cc	1.31	06/12/12"
+
+/*
+ *	misc.cc
+ *
+ *	This file contains various unclassified routines. Some main groups:
+ *		getname
+ *		Memory allocation
+ *		String handling
+ *		Property handling
+ *		Error message handling
+ *		Make internal state dumping
+ *		main routine support
+ */
+
+/*
+ * Included files
+ */
+#include <bsd/bsd.h>		/* bsd_signal() */
+#include <mksh/i18n.h>		/* get_char_semantics_value() */
+#include <mksh/misc.h>
+#include <mksdmsi18n/mksdmsi18n.h>
+#include <stdarg.h>		/* va_list, va_start(), va_end() */
+#include <stdlib.h>		/* mbstowcs() */
+#include <sys/signal.h>		/* SIG_DFL */
+#include <sys/wait.h>		/* wait() */
+
+#ifdef SUN5_0
+#include <string.h>		/* strerror() */
+#endif
+
+#if defined (HP_UX) || defined (linux)
+#include <unistd.h>
+#endif
+
+/*
+ * Defined macros
+ */
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+#ifdef SUN5_0
+extern "C" void		(*sigivalue)(int) = SIG_DFL;
+extern "C" void		(*sigqvalue)(int) = SIG_DFL;
+extern "C" void		(*sigtvalue)(int) = SIG_DFL;
+extern "C" void		(*sighvalue)(int) = SIG_DFL;
+#else
+static	void		(*sigivalue)(int) = (void (*) (int)) SIG_DFL;
+static	void		(*sigqvalue)(int) = (void (*) (int)) SIG_DFL;
+static	void		(*sigtvalue)(int) = (void (*) (int)) SIG_DFL;
+static	void		(*sighvalue)(int) = (void (*) (int)) SIG_DFL;
+#endif
+
+long	getname_bytes_count = 0;
+long	getname_names_count = 0;
+long	getname_struct_count = 0;
+
+long	freename_bytes_count = 0;
+long	freename_names_count = 0;
+long	freename_struct_count = 0;
+
+long	expandstring_count = 0;
+long	getwstring_count = 0;
+
+/*
+ * File table of contents
+ */
+static void	expand_string(register String string, register int length);
+
+#define	FATAL_ERROR_MSG_SIZE 200
+
+/*
+ *	getmem(size)
+ *
+ *	malloc() version that checks the returned value.
+ *
+ *	Return value:
+ *				The memory chunk we allocated
+ *
+ *	Parameters:
+ *		size		The size of the chunk we need
+ *
+ *	Global variables used:
+ */
+char *
+getmem(register int size)
+{
+	register char          *result = (char *) malloc((unsigned) size);
+	if (result == NULL) {
+		char buf[FATAL_ERROR_MSG_SIZE];
+		sprintf(buf, NOCATGETS("*** Error: malloc(%d) failed: %s\n"), size, strerror(errno));
+		strcat(buf, catgets(libmksdmsi18n_catd, 1, 126, "mksh: Fatal error: Out of memory\n"));
+		fputs(buf, stderr);
+#ifdef SUN5_0
+		exit_status = 1;
+#endif
+		exit(1);
+	}
+	return result;
+}
+
+/*
+ *	retmem(p)
+ *
+ *	Cover funtion for free() to make it possible to insert advises.
+ *
+ *	Parameters:
+ *		p		The memory block to free
+ *
+ *	Global variables used:
+ */
+void
+retmem(wchar_t *p)
+{
+	(void) free((char *) p);
+}
+
+void
+retmem_mb(caddr_t p)
+{
+	(void) free(p);
+}
+
+/*
+ *	getname_fn(name, len, dont_enter)
+ *
+ *	Hash a name string to the corresponding nameblock.
+ *
+ *	Return value:
+ *				The Name block for the string
+ *
+ *	Parameters:
+ *		name		The string we want to internalize
+ *		len		The length of that string
+ *		dont_enter	Don't enter the name if it does not exist
+ *
+ *	Global variables used:
+ *		funny		The vector of semantic tags for characters
+ *		hashtab		The hashtable used for the nametable
+ */
+Name
+getname_fn(wchar_t *name, register int len, register Boolean dont_enter, register Boolean * foundp)
+{
+	register int		length;
+	register wchar_t	*cap = name;
+	register Name		np;
+	static Name_rec		empty_Name;
+	char			*tmp_mbs_buffer = NULL;
+	char			*mbs_name = mbs_buffer;
+
+	/*
+	 * First figure out how long the string is.
+	 * If the len argument is -1 we count the chars here.
+	 */
+	if (len == FIND_LENGTH) {
+		length = wslen(name);
+	} else {
+		length = len;
+	}
+
+	Wstring ws;
+	ws.init(name, length);
+	if (length >= MAXPATHLEN) {
+		mbs_name = tmp_mbs_buffer = getmem((length * MB_LEN_MAX) + 1);
+	}
+	(void) wcstombs(mbs_name, ws.get_string(), (length * MB_LEN_MAX) + 1);
+
+	/* Look for the string */
+	if (dont_enter || (foundp != 0)) {
+		np = hashtab.lookup(mbs_name);
+		if (foundp != 0) {
+			*foundp = (np != 0) ? true : false;
+		}
+		if ((np != 0) || dont_enter) {
+			if(tmp_mbs_buffer != NULL) {
+				retmem_mb(tmp_mbs_buffer);
+			}
+			return np;
+		} else {
+			np = ALLOC(Name);
+		}
+	} else {
+		Boolean found;
+		np = hashtab.insert(mbs_name, found);
+		if (found) {
+			if(tmp_mbs_buffer != NULL) {
+				retmem_mb(tmp_mbs_buffer);
+			}
+			return np;
+		}
+	}
+	getname_struct_count += sizeof(struct _Name);
+	*np = empty_Name;
+
+	np->string_mb = strdup(mbs_name);
+	if(tmp_mbs_buffer != NULL) {
+		retmem_mb(tmp_mbs_buffer);
+		mbs_name = tmp_mbs_buffer = NULL;
+	}
+	getname_bytes_count += strlen(np->string_mb) + 1;
+	/* Fill in the new Name */
+	np->stat.time = file_no_time;
+	np->hash.length = length;
+	/* Scan the namestring to classify it */
+	for (cap = name, len = 0; --length >= 0;) {
+		len |= get_char_semantics_value(*cap++);
+	}
+	np->dollar = BOOLEAN((len & (int) dollar_sem) != 0);
+	np->meta = BOOLEAN((len & (int) meta_sem) != 0);
+	np->percent = BOOLEAN((len & (int) percent_sem) != 0);
+	np->wildcard = BOOLEAN((len & (int) wildcard_sem) != 0);
+	np->colon = BOOLEAN((len & (int) colon_sem) != 0);
+	np->parenleft = BOOLEAN((len & (int) parenleft_sem) != 0);
+	getname_names_count++;
+	return np;
+}
+
+void
+store_name(Name name)
+{
+	hashtab.insert(name);
+}
+
+void
+free_name(Name name)
+{
+	freename_names_count++;
+	freename_struct_count += sizeof(struct _Name);
+	freename_bytes_count += strlen(name->string_mb) + 1;
+	retmem_mb(name->string_mb);
+	for (Property next, p = name->prop; p != NULL; p = next) {
+		next = p->next;
+		free(p);
+	}
+	free(name);
+}
+
+/*
+ *	enable_interrupt(handler)
+ *
+ *	This routine sets a new interrupt handler for the signals make
+ *	wants to deal with.
+ *
+ *	Parameters:
+ *		handler		The function installed as interrupt handler
+ *
+ *	Static variables used:
+ *		sigivalue	The original signal handler
+ *		sigqvalue	The original signal handler
+ *		sigtvalue	The original signal handler
+ *		sighvalue	The original signal handler
+ */
+void
+enable_interrupt(register void (*handler) (int))
+{
+#ifdef SUN5_0
+	if (sigivalue != SIG_IGN) {
+#else
+	if (sigivalue != (void (*) (int)) SIG_IGN) {
+#endif
+		(void) bsd_signal(SIGINT, (SIG_PF) handler);
+	}
+#ifdef SUN5_0
+	if (sigqvalue != SIG_IGN) {
+#else
+	if (sigqvalue != (void (*) (int)) SIG_IGN) {
+#endif
+		(void) bsd_signal(SIGQUIT, (SIG_PF) handler);
+	}
+#ifdef SUN5_0
+	if (sigtvalue != SIG_IGN) {
+#else
+	if (sigtvalue != (void (*) (int)) SIG_IGN) {
+#endif
+		(void) bsd_signal(SIGTERM, (SIG_PF) handler);
+	}
+#ifdef SUN5_0
+	if (sighvalue != SIG_IGN) {
+#else
+	if (sighvalue != (void (*) (int)) SIG_IGN) {
+#endif
+		(void) bsd_signal(SIGHUP, (SIG_PF) handler);
+	}
+}
+
+/*
+ *	setup_char_semantics()
+ *
+ *	Load the vector char_semantics[] with lexical markers
+ *
+ *	Parameters:
+ *
+ *	Global variables used:
+ *		char_semantics	The vector of character semantics that we set
+ */
+void
+setup_char_semantics(void)
+{
+	char		*s;
+	wchar_t		wc_buffer[1];
+	int		entry;
+
+	if (svr4) {
+		s = "@-";
+	} else {
+		s = "=@-?!+";
+	}
+	for (s; MBTOWC(wc_buffer, s); s++) {
+		entry = get_char_semantics_entry(*wc_buffer);
+		char_semantics[entry] |= (int) command_prefix_sem;
+	}
+	char_semantics[dollar_char_entry] |= (int) dollar_sem;
+	for (s = "#|=^();&<>*?[]:$`'\"\\\n"; MBTOWC(wc_buffer, s); s++) {
+		entry = get_char_semantics_entry(*wc_buffer);
+		char_semantics[entry] |= (int) meta_sem;
+	}
+	char_semantics[percent_char_entry] |= (int) percent_sem;
+	for (s = "@*<%?^"; MBTOWC(wc_buffer, s); s++) {
+		entry = get_char_semantics_entry(*wc_buffer);
+		char_semantics[entry] |= (int) special_macro_sem;
+	}
+	for (s = "?[*"; MBTOWC(wc_buffer, s); s++) {
+		entry = get_char_semantics_entry(*wc_buffer);
+		char_semantics[entry] |= (int) wildcard_sem;
+	}
+	char_semantics[colon_char_entry] |= (int) colon_sem;
+	char_semantics[parenleft_char_entry] |= (int) parenleft_sem;
+}
+
+/*
+ *	errmsg(errnum)
+ *
+ *	Return the error message for a system call error
+ *
+ *	Return value:
+ *				An error message string
+ *
+ *	Parameters:
+ *		errnum		The number of the error we want to describe
+ *
+ *	Global variables used:
+ *		sys_errlist	A vector of error messages
+ *		sys_nerr	The size of sys_errlist
+ */
+char *
+errmsg(int errnum)
+{
+#ifdef linux
+	return strerror(errnum);
+#else // linux
+
+	extern int		sys_nerr;
+#ifdef SUN4_x
+	extern char		*sys_errlist[];
+#endif
+	char			*errbuf;
+
+	if ((errnum < 0) || (errnum > sys_nerr)) {
+		errbuf = getmem(6+1+11+1);
+		(void) sprintf(errbuf, catgets(libmksdmsi18n_catd, 1, 127, "Error %d"), errnum);
+		return errbuf;
+	} else {
+#ifdef SUN4_x
+		return(sys_errlist[errnum]);
+#endif
+#ifdef SUN5_0
+		return strerror(errnum);
+#endif
+
+	}
+#endif // linux
+}
+
+static char static_buf[MAXPATHLEN*3];
+
+/*
+ *	fatal_mksh(format, args...)
+ *
+ *	Print a message and die
+ *
+ *	Parameters:
+ *		format		printf type format string
+ *		args		Arguments to match the format
+ */
+/*VARARGS*/
+void
+fatal_mksh(char * message, ...)
+{
+	va_list args;
+	char    *buf = static_buf;
+	char	*mksh_fat_err = catgets(libmksdmsi18n_catd, 1, 128, "mksh: Fatal error: ");
+	char	*cur_wrk_dir = catgets(libmksdmsi18n_catd, 1, 129, "Current working directory: ");
+	int	mksh_fat_err_len = strlen(mksh_fat_err);
+
+	va_start(args, message);
+	(void) fflush(stdout);
+	(void) strcpy(buf, mksh_fat_err);
+	size_t buf_len = vsnprintf(static_buf + mksh_fat_err_len,
+				   sizeof(static_buf) - mksh_fat_err_len,
+				   message, args)
+			+ mksh_fat_err_len
+			+ strlen(cur_wrk_dir)
+			+ strlen(get_current_path_mksh())
+			+ 3; // "\n\n"
+	va_end(args);
+	if (buf_len >= sizeof(static_buf)) {
+		buf = getmem(buf_len);
+		(void) strcpy(buf, mksh_fat_err);
+		va_start(args, message);
+		(void) vsprintf(buf + mksh_fat_err_len, message, args);
+		va_end(args);
+	}
+	(void) strcat(buf, "\n");
+/*
+	if (report_pwd) {
+ */
+	if (1) {
+		(void) strcat(buf, cur_wrk_dir);
+		(void) strcat(buf, get_current_path_mksh());
+		(void) strcat(buf, "\n");
+	}
+	(void) fputs(buf, stderr);
+	(void) fflush(stderr);
+	if (buf != static_buf) {
+		retmem_mb(buf);
+	}
+#ifdef SUN5_0
+	exit_status = 1;
+#endif
+	exit(1);
+}
+
+/*
+ *	fatal_reader_mksh(format, args...)
+ *
+ *	Parameters:
+ *		format		printf style format string
+ *		args		arguments to match the format
+ */
+/*VARARGS*/
+void
+fatal_reader_mksh(char * pattern, ...)
+{
+	va_list args;
+	char	message[1000];
+
+	va_start(args, pattern);
+/*
+	if (file_being_read != NULL) {
+		WCSTOMBS(mbs_buffer, file_being_read);
+		if (line_number != 0) {
+			(void) sprintf(message,
+				       catgets(libmksdmsi18n_catd, 1, 130, "%s, line %d: %s"),
+				       mbs_buffer,
+				       line_number,
+				       pattern);
+		} else {
+			(void) sprintf(message,
+				       "%s: %s",
+				       mbs_buffer,
+				       pattern);
+		}
+		pattern = message;
+	}
+ */
+
+	(void) fflush(stdout);
+	(void) fprintf(stderr, catgets(libmksdmsi18n_catd, 1, 131, "mksh: Fatal error in reader: "));
+	(void) vfprintf(stderr, pattern, args);
+	(void) fprintf(stderr, "\n");
+	va_end(args);
+
+/*
+	if (temp_file_name != NULL) {
+		(void) fprintf(stderr,
+			       catgets(libmksdmsi18n_catd, 1, 132, "mksh: Temp-file %s not removed\n"),
+			       temp_file_name->string_mb);
+		temp_file_name = NULL;
+	}
+ */
+
+/*
+	if (report_pwd) {
+ */
+	if (1) {
+		(void) fprintf(stderr,
+			       catgets(libmksdmsi18n_catd, 1, 133, "Current working directory %s\n"),
+			       get_current_path_mksh());
+	}
+	(void) fflush(stderr);
+#ifdef SUN5_0
+	exit_status = 1;
+#endif
+	exit(1);
+}
+
+/*
+ *	warning_mksh(format, args...)
+ *
+ *	Print a message and continue.
+ *
+ *	Parameters:
+ *		format		printf type format string
+ *		args		Arguments to match the format
+ */
+/*VARARGS*/
+void
+warning_mksh(char * message, ...)
+{
+	va_list args;
+
+	va_start(args, message);
+	(void) fflush(stdout);
+	(void) fprintf(stderr, catgets(libmksdmsi18n_catd, 1, 134, "mksh: Warning: "));
+	(void) vfprintf(stderr, message, args);
+	(void) fprintf(stderr, "\n");
+	va_end(args);
+/*
+	if (report_pwd) {
+ */
+	if (1) {
+		(void) fprintf(stderr,
+			       catgets(libmksdmsi18n_catd, 1, 135, "Current working directory %s\n"),
+			       get_current_path_mksh());
+	}
+	(void) fflush(stderr);
+}
+
+/*
+ *	get_current_path_mksh()
+ *
+ *	Stuff current_path with the current path if it isnt there already.
+ *
+ *	Parameters:
+ *
+ *	Global variables used:
+ */
+char *
+get_current_path_mksh(void)
+{
+	char			pwd[(MAXPATHLEN * MB_LEN_MAX)];
+	static char		*current_path;
+
+	if (current_path == NULL) {
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+		getcwd(pwd, sizeof(pwd));
+#else
+		(void) getwd(pwd);
+#endif
+		if (pwd[0] == (int) nul_char) {
+			pwd[0] = (int) slash_char;
+			pwd[1] = (int) nul_char;
+		}
+		current_path = strdup(pwd);
+	}
+	return current_path;
+}
+
+/*
+ *	append_prop(target, type)
+ *
+ *	Create a new property and append it to the property list of a Name.
+ *
+ *	Return value:
+ *				A new property block for the target
+ *
+ *	Parameters:
+ *		target		The target that wants a new property
+ *		type		The type of property being requested
+ *
+ *	Global variables used:
+ */
+Property
+append_prop(register Name target, register Property_id type)
+{
+	register Property	*insert = &target->prop;
+	register Property	prop = *insert;
+	register int		size;
+
+	switch (type) {
+	case conditional_prop:
+		size = sizeof (struct Conditional);
+		break;
+	case line_prop:
+		size = sizeof (struct Line);
+		break;
+	case macro_prop:
+		size = sizeof (struct _Macro);
+		break;
+	case makefile_prop:
+		size = sizeof (struct Makefile);
+		break;
+	case member_prop:
+		size = sizeof (struct Member);
+		break;
+	case recursive_prop:
+		size = sizeof (struct Recursive);
+		break;
+	case sccs_prop:
+		size = sizeof (struct Sccs);
+		break;
+	case suffix_prop:
+		size = sizeof (struct Suffix);
+		break;
+	case target_prop:
+		size = sizeof (struct Target);
+		break;
+	case time_prop:
+		size = sizeof (struct STime);
+		break;
+	case vpath_alias_prop:
+		size = sizeof (struct Vpath_alias);
+		break;
+	case long_member_name_prop:
+		size = sizeof (struct Long_member_name);
+		break;
+	case macro_append_prop:
+		size = sizeof (struct _Macro_appendix);
+		break;
+	case env_mem_prop:
+		size = sizeof (struct _Env_mem);
+		break;
+	default:
+		fatal_mksh(catgets(libmksdmsi18n_catd, 1, 136, "Internal error. Unknown prop type %d"), type);
+	}
+	for (; prop != NULL; insert = &prop->next, prop = *insert);
+	size += PROPERTY_HEAD_SIZE;
+	*insert = prop = (Property) getmem(size);
+	memset((char *) prop, 0, size);
+	prop->type = type;
+	prop->next = NULL;
+	return prop;
+}
+
+/*
+ *	maybe_append_prop(target, type)
+ *
+ *	Append a property to the Name if none of this type exists
+ *	else return the one already there
+ *
+ *	Return value:
+ *				A property of the requested type for the target
+ *
+ *	Parameters:
+ *		target		The target that wants a new property
+ *		type		The type of property being requested
+ *
+ *	Global variables used:
+ */
+Property
+maybe_append_prop(register Name target, register Property_id type)
+{
+	register Property	prop;
+
+	if ((prop = get_prop(target->prop, type)) != NULL) {
+		return prop;
+	}
+	return append_prop(target, type);
+}
+
+/*
+ *	get_prop(start, type)
+ *
+ *	Scan the property list of a Name to find the next property
+ *	of a given type.
+ *
+ *	Return value:
+ *				The first property of the type, if any left
+ *
+ *	Parameters:
+ *		start		The first property block to check for type
+ *		type		The type of property block we need
+ *
+ *	Global variables used:
+ */
+Property
+get_prop(register Property start, register Property_id type)
+{
+	for (; start != NULL; start = start->next) {
+		if (start->type == type) {
+			return start;
+		}
+	}
+	return NULL;
+}
+
+/*
+ *	append_string(from, to, length)
+ *
+ *	Append a C string to a make string expanding it if nessecary
+ *
+ *	Parameters:
+ *		from		The source (C style) string
+ *		to		The destination (make style) string
+ *		length		The length of the from string
+ *
+ *	Global variables used:
+ */
+void
+append_string(register wchar_t *from, register String to, register int length)
+{
+	if (length == FIND_LENGTH) {
+		length = wslen(from);
+	}
+	if (to->buffer.start == NULL) {
+		expand_string(to, 32 + length);
+	}
+	if (to->buffer.end - to->text.p <= length) {
+		expand_string(to,
+			      (to->buffer.end - to->buffer.start) * 2 +
+			      length);
+	}
+	if (length > 0) {
+		(void) wsncpy(to->text.p, from, length);
+		to->text.p += length;
+	}
+	*(to->text.p) = (int) nul_char;
+}
+
+wchar_t * get_wstring(char *from) {
+	if(from == NULL) {
+		return NULL;
+	}
+	getwstring_count++;
+	wchar_t * wcbuf = ALLOC_WC(strlen(from) + 1);
+	mbstowcs(wcbuf, from, strlen(from)+1);
+	return wcbuf;
+}
+
+void
+append_string(register char *from, register String to, register int length)
+{
+	if (length == FIND_LENGTH) {
+		length = strlen(from);
+	}
+	if (to->buffer.start == NULL) {
+		expand_string(to, 32 + length);
+	}
+	if (to->buffer.end - to->text.p <= length) {
+		expand_string(to,
+			      (to->buffer.end - to->buffer.start) * 2 +
+			      length);
+	}
+	if (length > 0) {
+		(void) mbstowcs(to->text.p, from, length);
+		to->text.p += length;
+	}
+	*(to->text.p) = (int) nul_char;
+}
+
+/*
+ *	expand_string(string, length)
+ *
+ *	Allocate more memory for strings that run out of space.
+ *
+ *	Parameters:
+ *		string		The make style string we want to expand
+ *		length		The new length we need
+ *
+ *	Global variables used:
+ */
+static void
+expand_string(register String string, register int length)
+{
+	register wchar_t	*p;
+
+	if (string->buffer.start == NULL) {
+		/* For strings that have no memory allocated */
+		string->buffer.start =
+		  string->text.p =
+		    string->text.end =
+		      ALLOC_WC(length);
+		string->buffer.end = string->buffer.start + length;
+		string->text.p[0] = (int) nul_char;
+		string->free_after_use = true;
+		expandstring_count++;
+		return;
+	}
+	if (string->buffer.end - string->buffer.start >= length) {
+		/* If we really don't need more memory. */
+		return;
+	}
+	/*
+	 * Get more memory, copy the string and free the old buffer if
+	 * it is was malloc()'ed.
+	 */
+	expandstring_count++;
+	p = ALLOC_WC(length);
+	(void) wscpy(p, string->buffer.start);
+	string->text.p = p + (string->text.p - string->buffer.start);
+	string->text.end = p + (string->text.end - string->buffer.start);
+	string->buffer.end = p + length;
+	if (string->free_after_use) {
+		retmem(string->buffer.start);
+	}
+	string->buffer.start = p;
+	string->free_after_use = true;
+}
+
+/*
+ *	append_char(from, to)
+ *
+ *	Append one char to a make string expanding it if nessecary
+ *
+ *	Parameters:
+ *		from		Single character to append to string
+ *		to		The destination (make style) string
+ *
+ *	Global variables used:
+ */
+void
+append_char(wchar_t from, register String to)
+{
+	if (to->buffer.start == NULL) {
+		expand_string(to, 32);
+	}
+	if (to->buffer.end - to->text.p <= 2) {
+		expand_string(to, to->buffer.end - to->buffer.start + 32);
+	}
+	*(to->text.p)++ = from;
+	*(to->text.p) = (int) nul_char;
+}
+
+/*
+ *	handle_interrupt_mksh()
+ *
+ *	This is where C-C traps are caught.
+ */
+void
+handle_interrupt_mksh(int)
+{
+	(void) fflush(stdout);
+	/* Make sure the processes running under us terminate first. */
+	if (childPid > 0) {
+		kill(childPid, SIGTERM);
+		childPid = -1;
+	}
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+	while (wait((int *) NULL) != -1);
+#if defined(SUN5_0)
+	exit_status = 2;
+#endif
+#else
+	while (wait((union wait *) NULL) != -1);
+#endif
+	exit(2);
+}
+
+/*
+ *	setup_interrupt()
+ *
+ *	This routine saves the original interrupt handler pointers
+ *
+ *	Parameters:
+ *
+ *	Static variables used:
+ *		sigivalue	The original signal handler
+ *		sigqvalue	The original signal handler
+ *		sigtvalue	The original signal handler
+ *		sighvalue	The original signal handler
+ */
+void
+setup_interrupt(register void (*handler) (int))
+{
+#ifdef SUN5_0
+	sigivalue = bsd_signal(SIGINT, SIG_IGN);
+	sigqvalue = bsd_signal(SIGQUIT, SIG_IGN);
+	sigtvalue = bsd_signal(SIGTERM, SIG_IGN);
+	sighvalue = bsd_signal(SIGHUP, SIG_IGN);
+#else
+	sigivalue = (void (*) (int)) bsd_signal(SIGINT, SIG_IGN);
+	sigqvalue = (void (*) (int)) bsd_signal(SIGQUIT, SIG_IGN);
+	sigtvalue = (void (*) (int)) bsd_signal(SIGTERM, SIG_IGN);
+	sighvalue = (void (*) (int)) bsd_signal(SIGHUP, SIG_IGN);
+#endif
+	enable_interrupt(handler);
+}
+
+
+void
+mbstowcs_with_check(wchar_t *pwcs, const char *s, size_t n)
+{
+	if(mbstowcs(pwcs, s, n) == -1) {
+		fatal_mksh(catgets(libmksdmsi18n_catd, 1, 143, "The string `%s' is not valid in current locale"), s);
+	}
+}
+
+
+
+Wstring::Wstring()
+{
+	INIT_STRING_FROM_STACK(string, string_buf);
+}
+
+Wstring::Wstring(struct _Name * name)
+{
+	INIT_STRING_FROM_STACK(string, string_buf);
+	append_string(name->string_mb, &string, name->hash.length);
+}
+
+Wstring::~Wstring()
+{
+	if(string.free_after_use) {
+		retmem(string.buffer.start);
+	}
+}
+
+void
+Wstring::init(struct _Name * name)
+{
+	if(string.free_after_use) {
+		retmem(string.buffer.start);
+	}
+	INIT_STRING_FROM_STACK(string, string_buf);
+	append_string(name->string_mb, &string, name->hash.length);
+}
+
+void
+Wstring::init(wchar_t * name, unsigned length)
+{
+	INIT_STRING_FROM_STACK(string, string_buf);
+	append_string(name, &string, length);
+	string.buffer.start[length] = 0;
+}
+
+Boolean
+Wstring::equaln(wchar_t * str, unsigned length)
+{
+	return (Boolean)IS_WEQUALN(string.buffer.start, str, length);
+}
+
+Boolean
+Wstring::equaln(Wstring * str, unsigned length)
+{
+	return (Boolean)IS_WEQUALN(string.buffer.start, str->string.buffer.start, length);
+}
+
+Boolean
+Wstring::equal(wchar_t * str, unsigned off, unsigned length)
+{
+	return (Boolean)IS_WEQUALN(string.buffer.start + off, str, length);
+}
+
+Boolean
+Wstring::equal(wchar_t * str, unsigned off)
+{
+	return (Boolean)IS_WEQUAL(string.buffer.start + off, str);
+}
+
+Boolean
+Wstring::equal(wchar_t * str)
+{
+	return equal(str, 0);
+}
+
+Boolean
+Wstring::equal(Wstring * str, unsigned off, unsigned length)
+{
+	return (Boolean)IS_WEQUALN(string.buffer.start + off, str->string.buffer.start, length);
+}
+
+Boolean
+Wstring::equal(Wstring * str)
+{
+	return equal(str, 0);
+}
+
+Boolean
+Wstring::equal(Wstring * str, unsigned off)
+{
+	return (Boolean)IS_WEQUAL(string.buffer.start + off, str->string.buffer.start);
+}
+
+void
+Wstring::append_to_str(struct _String * str, unsigned off, unsigned length)
+{
+	append_string(string.buffer.start + off, str, length);
+}
+
+Name
+Name_set::lookup(const char *key)
+{
+	for (entry *node = root; node != 0;) {
+		int res = strcmp(key, node->name->string_mb);
+		if (res < 0) {
+			node = node->left;
+		} else if (res > 0) {
+			node = node->right;
+		} else {
+			return node->name;
+		}
+	}
+	return 0;
+}
+
+Name
+Name_set::insert(const char *key, Boolean &found)
+{
+	Name	name = 0;
+
+	if (root != 0) {
+		for (entry *node = root; name == 0;) {
+			int res = strcmp(key, node->name->string_mb);
+			if (res < 0) {
+				if (node->left != 0) {
+					node = node->left;
+				} else {
+					found = false;
+					name = ALLOC(Name);
+
+					node->left = new entry(name, node);
+					rebalance(node);
+				}
+			} else if (res > 0) {
+				if (node->right != 0) {
+					node = node->right;
+				} else {
+					found = false;
+					name = ALLOC(Name);
+
+					node->right = new entry(name, node);
+					rebalance(node);
+				}
+			} else {
+				found = true;
+				name = node->name;
+			}
+		}
+	} else {
+		found = false;
+		name = ALLOC(Name);
+
+		root = new entry(name, 0);
+	}
+	return name;
+}
+
+void
+Name_set::insert(Name name) {
+	if (root != 0) {
+		for (entry *node = root;;) {
+			int res = strcmp(name->string_mb, node->name->string_mb);
+			if (res < 0) {
+				if (node->left != 0) {
+					node = node->left;
+				} else {
+					node->left = new entry(name, node);
+					rebalance(node);
+					break;
+				}
+			} else if (res > 0) {
+				if (node->right != 0) {
+					node = node->right;
+				} else {
+					node->right = new entry(name, node);
+					rebalance(node);
+					break;
+				}
+			} else {
+				// should be an error: inserting already existing name
+				break;
+			}
+		}
+	} else {
+		root = new entry(name, 0);
+	}
+}
+
+void
+Name_set::rebalance(Name_set::entry *node) {
+	for (; node != 0; node = node->parent) {
+		entry *right = node->right;
+		entry *left = node->left;
+
+		unsigned rdepth = (right != 0) ? right->depth : 0;
+		unsigned ldepth = (left != 0) ? left->depth : 0;
+
+		if (ldepth > rdepth + 1) {
+			if ((node->left = left->right) != 0) {
+				left->right->parent = node;
+			}
+			if ((left->parent = node->parent) != 0) {
+				if (node == node->parent->right) {
+					node->parent->right = left;
+				} else {
+					node->parent->left = left;
+				}
+			} else {
+				root = left;
+			}
+			left->right = node;
+			node->parent = left;
+
+			node->setup_depth();
+			node = left;
+		} else if (rdepth > ldepth + 1) {
+			if ((node->right = right->left) != 0) {
+				right->left->parent = node;
+			}
+			if ((right->parent = node->parent) != 0) {
+				if (node == node->parent->right) {
+					node->parent->right = right;
+				} else {
+					node->parent->left = right;
+				}
+			} else {
+				root = right;
+			}
+			right->left = node;
+			node->parent = right;
+
+			node->setup_depth();
+			node = right;
+		}
+		node->setup_depth();
+	}
+}
+
+Name_set::iterator
+Name_set::begin() const {
+	for (entry *node = root; node != 0; node = node->left) {
+		if (node->left == 0) {
+			return iterator(node);
+		}
+	}
+	return iterator();
+}
+
+Name_set::iterator&
+Name_set::iterator::operator++() {
+	if (node != 0) {
+		if (node->right != 0) {
+			node = node->right;
+			while (node->left != 0) {
+				node = node->left;
+			}
+		} else {
+			while ((node->parent != 0) && (node->parent->right == node)) {
+				node = node->parent;
+			}
+			node = node->parent;
+		}
+	}
+	return *this;
+}
--- /dev/null	2015-05-20 11:04:22.000000000 -0400
+++ new/usr/src/cmd/make/lib/mksh/src/mksh.cc	2015-05-20 11:04:22.857360624 -0400
@@ -0,0 +1,286 @@
+/*
+ * 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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)mksh.cc 1.22 06/12/12
+ */
+
+#pragma	ident	"@(#)mksh.cc	1.22	06/12/12"
+
+/*
+ *	mksh.cc
+ *
+ *	Execute the command(s) of one Make or DMake rule
+ */
+
+/*
+ * Included files
+ */
+#if defined(TEAMWARE_MAKE_CMN) || defined(MAKETOOL) /* tolik */
+#	include <avo/util.h>
+#endif
+
+#include <mksh/dosys.h>		/* redirect_io() */
+#include <mksh/misc.h>		/* retmem() */
+#include <mksh/mksh.h>
+#include <mksdmsi18n/mksdmsi18n.h>
+#include <errno.h>
+#include <signal.h>
+
+#ifdef HP_UX
+	extern void (*sigset(int, void (*)(__harg)))(__harg);
+#endif
+
+/*
+ * Workaround for NFS bug. Sometimes, when running 'chdir' on a remote
+ * dmake server, it fails with "Stale NFS file handle" error.
+ * The second attempt seems to work.
+ */
+int
+my_chdir(char * dir) {
+	int res = chdir(dir);
+	if (res != 0 && (errno == ESTALE || errno == EAGAIN)) {
+		/* Stale NFS file handle. Try again */
+		res = chdir(dir);
+	}
+	return res;
+}
+
+
+/*
+ * File table of contents
+ */
+static void	change_sunpro_dependencies_value(char *oldpath, char *newpath);
+static void	init_mksh_globals(char *shell);
+static void	set_env_vars(char *env_list[]);
+
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+/*
+ *	Execute the command(s) of one Make or DMake rule
+ */
+int
+do_job(Avo_DmakeCommand *cmd_list[], char *env_list[], char *stdout_file, char *stderr_file, char *cwd, char *cnwd, int ignore, int silent, pathpt vroot_path, char *shell, int nice_prio)
+{
+	Boolean			always_exec_flag;
+	char			*cmd;
+	Avo_DmakeCommand	**cmd_list_p;
+	Name			command;
+	Boolean			do_not_exec_flag;
+	Boolean			ignore_flag;
+	int			length;
+	Boolean			make_refd_flag;
+	Boolean			meta_flag;
+	char			pathname[MAXPATHLEN];
+	Doname			result;
+	Boolean			silent_flag;
+	wchar_t			*tmp_wcs_buffer;
+
+	if ((childPid = fork()) < 0) {	/* error */
+		;
+	} else if (childPid > 0) {		/* parent */
+		;
+	} else {			/* child, mksh */
+		(void) sigset(SIGCHLD, SIG_DFL);
+		enable_interrupt(handle_interrupt_mksh);
+		/* set environment variables */
+		set_env_vars(env_list);
+		/* redirect stdout and stderr to temp files */
+		dup2(1, 2);	// Because fatal_mksh() prints error messages into
+				// stderr but dmake uses stderr for XDR communications
+				// and stdout for errors messages.
+		redirect_io(stdout_file, stderr_file);
+		/* try cd'ing to cwd */
+		if (my_chdir(cwd) != 0) {
+			/* try the netpath machine:pathname */
+			if (!avo_netpath_to_path(cnwd, pathname)) {
+				fatal_mksh(catgets(libmksdmsi18n_catd, 1, 137, "`cd %s' failed, and conversion of %s to automounter pathname also failed: %s"), cwd, cnwd, strerror(errno));
+			} else if (my_chdir(pathname) != 0) {
+				fatal_mksh(catgets(libmksdmsi18n_catd, 1, 138, "`cd %s' and `cd %s' both failed: %s"), cwd, pathname, strerror(errno));
+			}
+			/*
+			 * change the value of SUNPRO_DEPENDENCIES
+			 * to the new path.
+			 */
+			change_sunpro_dependencies_value(cwd, pathname);
+		}
+		init_mksh_globals(shell);
+		for (cmd_list_p = cmd_list;
+		     *cmd_list_p != (Avo_DmakeCommand *) NULL;
+		     cmd_list_p++) {
+			if ((*cmd_list_p)->ignore()) {
+				ignore_flag = true;
+			} else {
+				ignore_flag = false;
+			}
+			if ((*cmd_list_p)->silent()) {
+				silent_flag = true;
+			} else {
+				silent_flag = false;
+			}
+/*
+			if ((*cmd_list_p)->always_exec()) {
+				always_exec_flag = true;
+			} else {
+				always_exec_flag = false;
+			}
+ */
+			always_exec_flag = false;
+			if ((*cmd_list_p)->meta()) {
+				meta_flag = true;
+			} else {
+				meta_flag = false;
+			}
+			if ((*cmd_list_p)->make_refd()) {
+				make_refd_flag = true;
+			} else {
+				make_refd_flag = false;
+			}
+			if ((*cmd_list_p)->do_not_exec()) {
+				do_not_exec_flag = true;
+			} else {
+				do_not_exec_flag = false;
+			}
+			do_not_exec_rule = do_not_exec_flag;
+			cmd = (*cmd_list_p)->getCmd();
+			if ((length = strlen(cmd)) >= MAXPATHLEN) {
+				tmp_wcs_buffer = ALLOC_WC(length + 1);
+				(void) mbstowcs(tmp_wcs_buffer, cmd, length + 1);
+				command = GETNAME(tmp_wcs_buffer, FIND_LENGTH);
+				retmem(tmp_wcs_buffer);
+			} else {
+				MBSTOWCS(wcs_buffer, cmd);
+				command = GETNAME(wcs_buffer, FIND_LENGTH);
+			}
+			if ((command->hash.length > 0) &&
+			    (!silent_flag || do_not_exec_flag)) {
+				(void) printf("%s\n", command->string_mb);
+			}
+			result = dosys_mksh(command,
+					    ignore_flag,
+					    make_refd_flag,
+					    false, /* bugs #4085164 & #4990057 */
+					    /* BOOLEAN(silent_flag && ignore_flag), */
+					    always_exec_flag,
+					    (Name) NULL,
+					    false,
+					    NULL,
+					    NULL,
+					    vroot_path,
+					    nice_prio);
+			if (result == build_failed) {
+
+#ifdef PRINT_EXIT_STATUS
+				warning_mksh(NOCATGETS("I'm in do_job(), and dosys_mksh() returned result of build_failed."));
+#endif
+
+				if (silent_flag) {
+					(void) printf(catgets(libmksdmsi18n_catd, 1, 139, "The following command caused the error:\n%s\n"),
+						      command->string_mb);
+				}
+				if (!ignore_flag && !ignore) {
+
+#ifdef PRINT_EXIT_STATUS
+					warning_mksh(NOCATGETS("I'm in do_job(), and dosys_mksh() returned result of build_failed, exiting 1."));
+#endif
+
+					exit(1);
+				}
+			}
+		}
+
+#ifdef PRINT_EXIT_STATUS
+		warning_mksh(NOCATGETS("I'm in do_job(), exiting 0."));
+#endif
+
+	        exit(0);
+	}
+        return childPid;
+}
+#endif /* TEAMWARE_MAKE_CMN */
+
+static void
+set_env_vars(char *env_list[])
+{
+	char			**env_list_p;
+
+	for (env_list_p = env_list;
+	     *env_list_p != (char *) NULL;
+	     env_list_p++) {
+		putenv(*env_list_p);
+	}
+}
+
+static void
+init_mksh_globals(char *shell)
+{
+/*
+	MBSTOWCS(wcs_buffer, NOCATGETS("SHELL"));
+	shell_name = GETNAME(wcs_buffer, FIND_LENGTH);
+	MBSTOWCS(wcs_buffer, shell);
+	(void) SETVAR(shell_name, GETNAME(wcs_buffer, FIND_LENGTH), false);
+ */
+	char * dmake_shell;
+	if ((dmake_shell = getenv(NOCATGETS("DMAKE_SHELL"))) == NULL) {
+		dmake_shell = shell;
+	} 
+	MBSTOWCS(wcs_buffer, dmake_shell);
+	shell_name = GETNAME(wcs_buffer, FIND_LENGTH);
+}
+
+/*
+ * Change the pathname in the value of the SUNPRO_DEPENDENCIES env variable
+ * from oldpath to newpath.
+ */
+static void
+change_sunpro_dependencies_value(char *oldpath, char *newpath)
+{
+	char		buf[MAXPATHLEN];
+	static char	*env;
+	int		length;
+	int		oldpathlen;
+	char		*sp_dep_value;
+
+	/* check if SUNPRO_DEPENDENCIES is set in the environment */
+	if ((sp_dep_value = getenv(NOCATGETS("SUNPRO_DEPENDENCIES"))) != NULL) {
+		oldpathlen = strlen(oldpath);
+		/* check if oldpath is indeed in the value of SUNPRO_DEPENDENCIES */
+		if (strncmp(oldpath, sp_dep_value, oldpathlen) == 0) {
+			(void) sprintf(buf,
+				       "%s%s",
+				       newpath,
+				       sp_dep_value + oldpathlen);
+			length = 2 +
+				strlen(NOCATGETS("SUNPRO_DEPENDENCIES")) +
+				strlen(buf);
+			env = getmem(length);
+			(void) sprintf(env,
+				       "%s=%s",
+				       NOCATGETS("SUNPRO_DEPENDENCIES"),
+				       buf);
+			(void) putenv(env);
+		}
+	}
+}
+
+
--- /dev/null	2015-05-20 11:04:23.000000000 -0400
+++ new/usr/src/cmd/make/lib/mksh/src/read.cc	2015-05-20 11:04:23.051874033 -0400
@@ -0,0 +1,174 @@
+/*
+ * 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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)read.cc 1.11 06/12/12
+ */
+
+#pragma	ident	"@(#)read.cc	1.11	06/12/12"
+
+/*
+ *	read.c
+ *
+ *	This file contains the makefile reader.
+ */
+
+/*
+ * Included files
+ */
+#include <mksh/misc.h>		/* retmem() */
+#include <mksh/read.h>
+#include <mksdmsi18n/mksdmsi18n.h>
+#include <sys/uio.h>		/* read() */
+#include <unistd.h>		/* close(), unlink(), read() */
+
+#define	STRING_LEN_TO_CONVERT	(8*1024)
+
+/*
+ *	get_next_block_fn(source)
+ *
+ *	Will get the next block of text to read either
+ *	by popping one source bVSIZEOFlock of the stack of Sources
+ *	or by reading some more from the makefile.
+ *
+ *	Return value:
+ *				The new source block to read from
+ *
+ *	Parameters:
+ *		source		The old source block
+ *
+ *	Global variables used:
+ *		file_being_read	The name of the current file, error msg
+ */
+Boolean		make_state_locked;
+Source
+get_next_block_fn(register Source source)
+{
+	register off_t		to_read;
+	register int		length;
+	register size_t		num_wc_chars;
+	char			ch_save;
+	char			*ptr;
+
+	if (source == NULL) {
+		return NULL;
+	}
+	if ((source->fd < 0) || 
+		((source->bytes_left_in_file <= 0) &&
+			(source->inp_buf_ptr >= source->inp_buf_end))) {
+		/* We can't read from the makefile, so pop the source block */
+		if (source->fd > 2) {
+			(void) close(source->fd);
+			if (make_state_lockfile != NULL) {
+				(void) unlink(make_state_lockfile);
+				retmem_mb(make_state_lockfile);
+				make_state_lockfile = NULL;
+				make_state_locked = false;
+			}
+		}
+		if (source->string.free_after_use &&
+		    (source->string.buffer.start != NULL)) {
+			retmem(source->string.buffer.start);
+			source->string.buffer.start = NULL;
+		}
+		if (source->inp_buf != NULL) {
+			retmem_mb(source->inp_buf);
+			source->inp_buf = NULL;
+		}
+		source = source->previous;
+		if (source != NULL) {
+			source->error_converting = false;
+		}
+		return source;
+	}
+	if (source->bytes_left_in_file > 0) {
+	/*
+	 * Read the whole makefile.
+	 * Hopefully the kernel managed to prefetch the stuff.
+	 */
+		to_read = source->bytes_left_in_file;
+	 	source->inp_buf_ptr = source->inp_buf = getmem(to_read + 1);
+		source->inp_buf_end = source->inp_buf + to_read;
+		length = read(source->fd, source->inp_buf, (unsigned int) to_read);
+		if (length != to_read) {
+			WCSTOMBS(mbs_buffer, file_being_read);
+			if (length == 0) {
+				fatal_mksh(catgets(libmksdmsi18n_catd, 1, 140, "Error reading `%s': Premature EOF"),
+				      mbs_buffer);
+			} else {
+				fatal_mksh(catgets(libmksdmsi18n_catd, 1, 141, "Error reading `%s': %s"),
+				      mbs_buffer,
+				      errmsg(errno));
+			}
+		}
+		*source->inp_buf_end = nul_char;
+		source->bytes_left_in_file = 0;
+	}
+	/*
+	 * Try to convert the next piece.
+	 */
+	ptr = source->inp_buf_ptr + STRING_LEN_TO_CONVERT;
+	if (ptr > source->inp_buf_end) {
+		ptr = source->inp_buf_end;
+	}
+	for (num_wc_chars = 0; ptr > source->inp_buf_ptr; ptr--) {
+		ch_save = *ptr;
+		*ptr = nul_char;
+		num_wc_chars = mbstowcs(source->string.text.end,
+					source->inp_buf_ptr,
+					STRING_LEN_TO_CONVERT);
+		*ptr = ch_save;
+		if (num_wc_chars != (size_t)-1) {
+			break;
+		}
+	}
+		
+	if ((int) num_wc_chars == (size_t)-1) {
+		source->error_converting = true;
+		return source;
+	}
+
+	source->error_converting = false;
+	source->inp_buf_ptr = ptr;
+	source->string.text.end += num_wc_chars;
+	*source->string.text.end = 0;
+
+	if (source->inp_buf_ptr >= source->inp_buf_end) {
+		if (*(source->string.text.end - 1) != (int) newline_char) {
+			WCSTOMBS(mbs_buffer, file_being_read);
+			warning_mksh(catgets(libmksdmsi18n_catd, 1, 142, "newline is not last character in file %s"),
+					     mbs_buffer);
+			*source->string.text.end++ = (int) newline_char;
+			*source->string.text.end = (int) nul_char;
+			*source->string.buffer.end++;
+		}
+		if (source->inp_buf != NULL) {
+			retmem_mb(source->inp_buf);
+			source->inp_buf = NULL;
+		}
+	}
+	return source;
+}
+
+
--- /dev/null	2015-05-20 11:04:23.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/Makefile	2015-05-20 11:04:23.249577847 -0400
@@ -0,0 +1,29 @@
+#
+# 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 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.5 06/12/12
+#
+
+TOP =		../../..
+include $(TOP)/rules/variant.mk
+include $(TOP)/rules/derived.mk
--- /dev/null	2015-05-20 11:04:23.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/src/Makefile	2015-05-20 11:04:23.438328757 -0400
@@ -0,0 +1,49 @@
+#
+# 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 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.3 06/12/12
+#
+
+# Generic makefile for use in src directories.  Knows how to make common things
+# in the right $(VARIANT) directory.
+
+include $(TOP)/rules/variant.mk
+
+all :=		TARG = all 
+install :=		TARG = install 
+clean :=		TARG = clean 
+test :=		TARG = test
+l10n_install :=	TARG = l10n_install
+i18n_install :=	TARG = i18n_install
+
+SRC =		../src
+MFLAGS += 	SRC=$(SRC)
+
+# See $(TOP)/rules/master.mk for how these are built.
+%.h %.cc %.C %.E %.o all install clean test l10n_install i18n_install: FRC
+	@ if [ ! -d ../$(VARIANT) ]; then \
+		mkdir ../$(VARIANT) ; \
+	fi
+	cd ../$(VARIANT); $(MAKE) $(MFLAGS) -f $(SRC)/Variant.mk DESTDIR=$(DESTDIR) $@
+
+FRC:
--- /dev/null	2015-05-20 11:04:23.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/src/Variant.mk	2015-05-20 11:04:23.625843621 -0400
@@ -0,0 +1,71 @@
+#
+# 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 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Variant.mk 1.28 06/12/12
+#
+
+TOP =		../../../..
+include $(TOP)/rules/master.mk
+include $(TOP)/rules/dmake.mk
+
+PKG_TOP =	$(TOP)/Make
+CPPFLAGS +=	-I$(PKG_TOP)/include
+
+CCSRCS =	\
+		access.cc \
+		args.cc \
+		chdir.cc \
+		chmod.cc \
+		chown.cc \
+		chroot.cc \
+		creat.cc \
+		execve.cc \
+		lock.cc \
+		lstat.cc \
+		mkdir.cc \
+		mount.cc \
+		open.cc \
+		readlink.cc \
+		report.cc \
+		rmdir.cc \
+		stat.cc \
+		statfs.cc \
+		truncate.cc \
+		unlink.cc \
+		unmount.cc \
+		utimes.cc \
+		vroot.cc \
+		setenv.cc
+
+
+HDRS_DIR =	$(PKG_TOP)/include/vroot
+
+.INIT: $(HDRS_DIR)/args.h $(HDRS_DIR)/report.h $(HDRS_DIR)/vroot.h
+
+LIBNAME =	libvroot.a
+MSG_FILE = libvroot.msg
+I18N_DIRS = $(SRC)
+
+include $(TOP)/Make/lib/Lib.mk
+include $(TOP)/rules/lib.mk
+
--- /dev/null	2015-05-20 11:04:23.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/src/access.cc	2015-05-20 11:04:23.815199671 -0400
@@ -0,0 +1,46 @@
+/*
+ * 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 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)access.cc 1.4 06/12/12
+ */
+
+#pragma	ident	"@(#)access.cc	1.4	06/12/12"
+
+#include <unistd.h>
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int	access_thunk(char *path)
+{
+	vroot_result= access(path, vroot_args.access.mode);
+	return((vroot_result == 0) || (errno != ENOENT));
+}
+
+int	access_vroot(char *path, int mode, pathpt vroot_path, pathpt vroot_vroot)
+{
+	vroot_args.access.mode= mode;
+	translate_with_thunk(path, access_thunk, vroot_path, vroot_vroot, rw_read);
+	return(vroot_result);
+}
--- /dev/null	2015-05-20 11:04:24.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/src/args.cc	2015-05-20 11:04:24.006509090 -0400
@@ -0,0 +1,35 @@
+/*
+ * 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 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)args.cc 1.3 06/12/12
+ */
+
+#pragma	ident	"@(#)args.cc	1.3	06/12/12"
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+union Args	vroot_args;
+int		vroot_result;
--- /dev/null	2015-05-20 11:04:24.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/src/chdir.cc	2015-05-20 11:04:24.195117870 -0400
@@ -0,0 +1,45 @@
+/*
+ * 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 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)chdir.cc 1.4 06/12/12
+ */
+
+#pragma	ident	"@(#)chdir.cc	1.4	06/12/12"
+
+#include <unistd.h>
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int	chdir_thunk(char *path)
+{
+	vroot_result= chdir(path);
+	return(vroot_result == 0);
+}
+
+int	chdir_vroot(char *path, pathpt vroot_path, pathpt vroot_vroot)
+{
+	translate_with_thunk(path, chdir_thunk, vroot_path, vroot_vroot, rw_read);
+	return(vroot_result);
+}
--- /dev/null	2015-05-20 11:04:24.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/src/chmod.cc	2015-05-20 11:04:24.384578796 -0400
@@ -0,0 +1,50 @@
+/*
+ * 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 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)chmod.cc 1.4 06/12/12
+ */
+
+#pragma	ident	"@(#)chmod.cc	1.4	06/12/12"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+extern int chmod(const char *path, mode_t mode);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int	chmod_thunk(char *path)
+{
+	vroot_result= chmod(path, vroot_args.chmod.mode);
+	return(vroot_result == 0);
+}
+
+int	chmod_vroot(char *path, int mode, pathpt vroot_path, pathpt vroot_vroot)
+{
+	vroot_args.chmod.mode= mode;
+	translate_with_thunk(path, chmod_thunk, vroot_path, vroot_vroot, rw_read);
+	return(vroot_result);
+}
--- /dev/null	2015-05-20 11:04:24.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/src/chown.cc	2015-05-20 11:04:24.573811972 -0400
@@ -0,0 +1,51 @@
+/*
+ * 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 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)chown.cc 1.4 06/12/12
+ */
+
+#pragma	ident	"@(#)chown.cc	1.4	06/12/12"
+
+#include <unistd.h>
+#include <sys/types.h>
+
+extern int chown(const char *path, uid_t owner, gid_t group);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int	chown_thunk(char *path)
+{
+	vroot_result= chown(path, vroot_args.chown.user, vroot_args.chown.group);
+	return(vroot_result == 0);
+}
+
+int	chown_vroot(char *path, int user, int group, pathpt vroot_path, pathpt vroot_vroot)
+{
+	vroot_args.chown.user= user;
+	vroot_args.chown.group= group;
+	translate_with_thunk(path, chown_thunk, vroot_path, vroot_vroot, rw_read);
+	return(vroot_result);
+}
--- /dev/null	2015-05-20 11:04:24.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/src/chroot.cc	2015-05-20 11:04:24.763068977 -0400
@@ -0,0 +1,48 @@
+/*
+ * 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 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)chroot.cc 1.4 06/12/12
+ */
+
+#pragma	ident	"@(#)chroot.cc	1.4	06/12/12"
+
+#include <unistd.h>
+
+extern int chroot(const char *path);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int	chroot_thunk(char *path)
+{
+	vroot_result= chroot(path);
+	return(vroot_result == 0);
+}
+
+int	chroot_vroot(char *path, pathpt vroot_path, pathpt vroot_vroot)
+{
+	translate_with_thunk(path, chroot_thunk, vroot_path, vroot_vroot, rw_read);
+	return(vroot_result);
+}
--- /dev/null	2015-05-20 11:04:24.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/src/creat.cc	2015-05-20 11:04:24.952647507 -0400
@@ -0,0 +1,51 @@
+/*
+ * 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 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)creat.cc 1.4 06/12/12
+ */
+
+#pragma	ident	"@(#)creat.cc	1.4	06/12/12"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+extern int creat(const char *path, mode_t mode);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int	creat_thunk(char *path)
+{
+	vroot_result= creat(path, vroot_args.creat.mode);
+	return(vroot_result >= 0);
+}
+
+int	creat_vroot(char *path, int mode, pathpt vroot_path, pathpt vroot_vroot)
+{
+	vroot_args.creat.mode= mode;
+	translate_with_thunk(path, creat_thunk, vroot_path, vroot_vroot, rw_write);
+	return(vroot_result);
+}
--- /dev/null	2015-05-20 11:04:25.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/src/execve.cc	2015-05-20 11:04:25.143150918 -0400
@@ -0,0 +1,54 @@
+/*
+ * 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 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)execve.cc 1.4 06/12/12
+ */
+
+#pragma	ident	"@(#)execve.cc	1.4	06/12/12"
+
+#include <unistd.h>
+
+extern int execve (const char *path, char *const argv[], char *const envp[]);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int	execve_thunk(char *path)
+{
+	execve(path, vroot_args.execve.argv, vroot_args.execve.environ);
+	switch (errno) {
+		case ETXTBSY:
+		case ENOEXEC: return 1;
+		default: return 0;
+	}
+}
+
+int	execve_vroot(char *path, char **argv, char **environ, pathpt vroot_path, pathpt vroot_vroot)
+{
+	vroot_args.execve.argv= argv;
+	vroot_args.execve.environ= environ;
+	translate_with_thunk(path, execve_thunk, vroot_path, vroot_vroot, rw_read);
+	return(-1);
+}
--- /dev/null	2015-05-20 11:04:25.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/src/libvroot.msg	2015-05-20 11:04:25.338167933 -0400
@@ -0,0 +1,38 @@
+
+$quote "
+
+
+$set	1
+$
+$ 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 1996 Sun Microsystems, Inc. All rights reserved.
+$ Use is subject to license terms.
+$
+$ @(#)libvroot.msg 1.2 06/12/12
+$
+142	"file_lock: file %s is already locked.\n"
+143	"file_lock: will periodically check the lockfile %s for two minutes.\n"
+144	"Current working directory %s\n"
+145	"Could not lock file `%s'; "
+146	" failed - "
+147	"Couldn't write to %s"
+148	"Cannot open `%s' for writing\n"
+149	"Cannot open %s for writing\n"
--- /dev/null	2015-05-20 11:04:25.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/src/lock.cc	2015-05-20 11:04:25.526850628 -0400
@@ -0,0 +1,196 @@
+/*
+ * 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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)lock.cc 1.17 06/12/12
+ */
+
+#pragma	ident	"@(#)lock.cc	1.17	06/12/12"
+
+#include <avo/intl.h>	/* for NOCATGETS */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/errno.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <vroot/vroot.h>
+#include <mksdmsi18n/mksdmsi18n.h>
+#include <signal.h>
+#include <errno.h>			/* errno */
+
+#if !defined(linux)
+extern	char		*sys_errlist[];
+extern	int		sys_nerr;
+#endif
+
+static	void		file_lock_error(char *msg, char *file, char *str, int arg1, int arg2);
+
+#define BLOCK_INTERUPTS sigfillset(&newset) ; \
+	sigprocmask(SIG_SETMASK, &newset, &oldset)
+
+#define UNBLOCK_INTERUPTS \
+	sigprocmask(SIG_SETMASK, &oldset, &newset)
+
+/*
+ * This code stolen from the NSE library and changed to not depend
+ * upon any NSE routines or header files.
+ *
+ * Simple file locking.
+ * Create a symlink to a file.  The "test and set" will be
+ * atomic as creating the symlink provides both functions.
+ *
+ * The timeout value specifies how long to wait for stale locks
+ * to disappear.  If the lock is more than 'timeout' seconds old
+ * then it is ok to blow it away.  This part has a small window
+ * of vunerability as the operations of testing the time,
+ * removing the lock and creating a new one are not atomic.
+ * It would be possible for two processes to both decide to blow
+ * away the lock and then have process A remove the lock and establish
+ * its own, and then then have process B remove the lock which accidentily
+ * removes A's lock rather than the stale one.
+ *
+ * A further complication is with the NFS.  If the file in question is
+ * being served by an NFS server, then its time is set by that server.
+ * We can not use the time on the client machine to check for a stale
+ * lock.  Therefore, a temp file on the server is created to get
+ * the servers current time.
+ *
+ * Returns an error message.  NULL return means the lock was obtained.
+ *
+ * 12/6/91 Added the parameter "file_locked".  Before this parameter 
+ * was added, the calling procedure would have to wait for file_lock() 
+ * to return before it sets the flag. If the user interrupted "make"
+ * between the time the lock was acquired and the time file_lock()
+ * returns, make wouldn't know that the file has been locked, and therefore
+ * it wouldn' remove the lock. Setting the flag right after locking the file
+ * makes this window much smaller.
+ */
+
+int
+file_lock(char *name, char *lockname, int *file_locked, int timeout)
+{
+	int		counter = 0;
+	static char	msg[MAXPATHLEN+1];
+	int		printed_warning = 0;
+	int		r;
+	struct stat	statb;
+	sigset_t newset;
+	sigset_t oldset;
+
+	*file_locked = 0;	
+	if (timeout <= 0) {
+		timeout = 120;
+	}
+	for (;;) {
+		BLOCK_INTERUPTS;
+		r = symlink(name, lockname);
+		if (r == 0) {
+			*file_locked = 1;
+			UNBLOCK_INTERUPTS;
+			return 0; /* success */
+		}
+		UNBLOCK_INTERUPTS;
+
+		if (errno != EEXIST) {
+			file_lock_error(msg, name, NOCATGETS("symlink(%s, %s)"),
+			    (int) name, (int) lockname);
+			fprintf(stderr, "%s", msg);
+			return errno;
+		}
+
+		counter = 0;
+		for (;;) {
+			sleep(1); 
+			r = lstat(lockname, &statb);
+			if (r == -1) {
+				/*
+				 * The lock must have just gone away - try 
+				 * again.
+				 */
+				break;
+			}
+
+			if ((counter > 5) && (!printed_warning)) {
+				/* Print waiting message after 5 secs */
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+				(void) getcwd(msg, MAXPATHLEN);
+#else
+				(void) getwd(msg);
+#endif
+				fprintf(stderr,
+					catgets(libmksdmsi18n_catd, 1, 162, "file_lock: file %s is already locked.\n"),
+					name);
+				fprintf(stderr,
+					catgets(libmksdmsi18n_catd, 1, 163, "file_lock: will periodically check the lockfile %s for two minutes.\n"),
+					lockname);
+				fprintf(stderr,
+					catgets(libmksdmsi18n_catd, 1, 144, "Current working directory %s\n"),
+					msg);
+
+				printed_warning = 1;
+			}
+
+			if (++counter > timeout ) {
+				/*
+				 * Waited enough - return an error..
+				 */
+				return EEXIST;
+			}
+		}
+	}
+	/* NOTREACHED */
+}
+
+/*
+ * Format a message telling why the lock could not be created.
+ */
+static	void
+file_lock_error(char *msg, char *file, char *str, int arg1, int arg2)
+{
+	int		len;
+
+	sprintf(msg, catgets(libmksdmsi18n_catd, 1, 145, "Could not lock file `%s'; "), file);
+	len = strlen(msg);
+	sprintf(&msg[len], str, arg1, arg2);
+	strcat(msg, catgets(libmksdmsi18n_catd, 1, 146, " failed - "));
+#if !defined(linux)
+	if (errno < sys_nerr) {
+#ifdef SUN4_x
+		strcat(msg, sys_errlist[errno]);
+#endif
+#ifdef SUN5_0
+		strcat(msg, strerror(errno));
+#endif
+	} else {
+		len = strlen(msg);
+		sprintf(&msg[len], NOCATGETS("errno %d"), errno);
+	}
+#else
+	strcat(msg, strerror(errno));
+#endif
+}
+
--- /dev/null	2015-05-20 11:04:25.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/src/lstat.cc	2015-05-20 11:04:25.718718902 -0400
@@ -0,0 +1,50 @@
+/*
+ * 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 1998 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)lstat.cc 1.6 06/12/12
+ */
+
+#pragma	ident	"@(#)lstat.cc	1.6	06/12/12"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+extern int lstat(const char *path, struct stat *buf);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int	lstat_thunk(char *path)
+{
+	vroot_result= lstat(path, vroot_args.lstat.buffer);
+	return(vroot_result == 0);
+}
+
+int	lstat_vroot(char *path, struct stat *buffer, pathpt vroot_path, pathpt vroot_vroot)
+{
+	vroot_args.lstat.buffer= buffer;
+	translate_with_thunk(path, lstat_thunk, vroot_path, vroot_vroot, rw_read);
+	return(vroot_result);
+}
--- /dev/null	2015-05-20 11:04:25.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/src/mkdir.cc	2015-05-20 11:04:25.908359688 -0400
@@ -0,0 +1,50 @@
+/*
+ * 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 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)mkdir.cc 1.4 06/12/12
+ */
+
+#pragma	ident	"@(#)mkdir.cc	1.4	06/12/12"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+extern int mkdir(const char *path, mode_t mode);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int	mkdir_thunk(char *path)
+{
+	vroot_result= mkdir(path, vroot_args.mkdir.mode);
+	return(vroot_result == 0);
+}
+
+int	mkdir_vroot(char *path, int mode, pathpt vroot_path, pathpt vroot_vroot)
+{
+	vroot_args.mkdir.mode= mode;
+	translate_with_thunk(path, mkdir_thunk, vroot_path, vroot_vroot, rw_write);
+	return(vroot_result);
+}
--- /dev/null	2015-05-20 11:04:26.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/src/mount.cc	2015-05-20 11:04:26.098631201 -0400
@@ -0,0 +1,53 @@
+/*
+ * 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 1995 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)mount.cc 1.5 06/12/12
+ */
+
+#pragma	ident	"@(#)mount.cc	1.5	06/12/12"
+
+#include <sys/types.h>
+#include <sys/mount.h>
+
+#ifndef HP_UX
+extern int mount(const char *spec, const char *dir, int mflag, ...);
+#endif
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int	mount_thunk(char *path)
+{
+	vroot_result= mount(path, vroot_args.mount.name, vroot_args.mount.mode);
+	return(vroot_result == 0);
+}
+
+int	mount_vroot(char *target, char *name, int mode, pathpt vroot_path, pathpt vroot_vroot)
+{
+	vroot_args.mount.name= name;
+	vroot_args.mount.mode= mode;
+	translate_with_thunk(target, mount_thunk, vroot_path, vroot_vroot, rw_read);
+	return(vroot_result);
+}
--- /dev/null	2015-05-20 11:04:26.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/src/open.cc	2015-05-20 11:04:26.288554241 -0400
@@ -0,0 +1,53 @@
+/*
+ * 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 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)open.cc 1.4 06/12/12
+ */
+
+#pragma	ident	"@(#)open.cc	1.4	06/12/12"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+extern int open(const char *path, int oflag, ...);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int	open_thunk(char *path)
+{
+	vroot_result= open(path, vroot_args.open.flags, vroot_args.open.mode);
+	return(vroot_result >= 0);
+}
+
+int	open_vroot(char *path, int flags, int mode, pathpt vroot_path, pathpt vroot_vroot)
+{
+	vroot_args.open.flags= flags;
+	vroot_args.open.mode= mode;
+	translate_with_thunk(path, open_thunk, vroot_path, vroot_vroot,
+				((flags & (O_CREAT|O_APPEND)) != 0) ? rw_write : rw_read);
+	return(vroot_result);
+}
--- /dev/null	2015-05-20 11:04:26.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/src/readlink.cc	2015-05-20 11:04:26.477579005 -0400
@@ -0,0 +1,50 @@
+/*
+ * 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 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)readlink.cc 1.4 06/12/12
+ */
+
+#pragma	ident	"@(#)readlink.cc	1.4	06/12/12"
+
+#include <unistd.h>
+
+extern int readlink(const char *path, void *buf, size_t bufsiz);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int	readlink_thunk(char *path)
+{
+	vroot_result= readlink(path, vroot_args.readlink.buffer, vroot_args.readlink.buffer_size);
+	return(vroot_result >= 0);
+}
+
+int	readlink_vroot(char *path, char *buffer, int buffer_size, pathpt vroot_path, pathpt vroot_vroot)
+{
+	vroot_args.readlink.buffer= buffer;
+	vroot_args.readlink.buffer_size= buffer_size;
+	translate_with_thunk(path, readlink_thunk, vroot_path, vroot_vroot, rw_read);
+	return(vroot_result);
+}
--- /dev/null	2015-05-20 11:04:26.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/src/report.cc	2015-05-20 11:04:26.666399322 -0400
@@ -0,0 +1,396 @@
+/*
+ * 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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)report.cc 1.17 06/12/12
+ */
+
+#pragma	ident	"@(#)report.cc	1.17	06/12/12"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <vroot/report.h>
+#include <vroot/vroot.h>
+#include <mksdmsi18n/mksdmsi18n.h>
+#include <avo/intl.h>	/* for NOCATGETS */
+#include <mk/defs.h>	/* for tmpdir */
+
+static	FILE	*report_file;
+static	FILE	*command_output_fp;
+static	char	*target_being_reported_for;
+static	char	*search_dir;
+static  char	command_output_tmpfile[30];
+static	int	is_path = 0;
+static	char	sfile[MAXPATHLEN];
+extern "C" {
+static	void	(*warning_ptr) (char *, ...) = (void (*) (char *, ...)) NULL;
+}
+
+FILE *
+get_report_file(void)
+{
+	return(report_file);
+}
+
+char *
+get_target_being_reported_for(void)
+{
+	return(target_being_reported_for);
+}
+
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+extern "C" {
+static void
+close_report_file(void)
+{
+	(void)fputs("\n", report_file);
+	(void)fclose(report_file);
+}
+} // extern "C"
+#else
+static void
+close_report_file(int, ...)
+{
+	(void)fputs("\n", report_file);
+	(void)fclose(report_file);
+}
+#endif
+
+static void
+clean_up(FILE *nse_depinfo_fp, FILE *merge_fp, char *nse_depinfo_file, char *merge_file, int unlinkf)
+{
+	fclose(nse_depinfo_fp);
+	fclose(merge_fp);
+	fclose(command_output_fp);
+	unlink(command_output_tmpfile);
+	if (unlinkf)
+		unlink(merge_file);
+	else
+		rename(merge_file, nse_depinfo_file);
+}
+
+
+/*
+ *  Update the file, if necessary.  We don't want to rewrite
+ *  the file if we don't have to because we don't want the time of the file
+ *  to change in that case.
+ */
+
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+extern "C" {
+static void
+close_file(void)
+#else
+static void
+close_file(int, ...)
+#endif
+{
+	char		line[MAXPATHLEN+2];
+	char		buf[MAXPATHLEN+2];
+	FILE		*nse_depinfo_fp;
+	FILE		*merge_fp;
+	char		nse_depinfo_file[MAXPATHLEN];
+	char		merge_file[MAXPATHLEN];
+	char		lock_file[MAXPATHLEN];
+	int		err;
+	int		len;
+	int		changed = 0;
+	int		file_locked;
+
+	fprintf(command_output_fp, "\n");
+	fclose(command_output_fp);
+	if ((command_output_fp = fopen(command_output_tmpfile, "r")) == NULL) {
+		return;
+	}
+	sprintf(nse_depinfo_file, "%s/%s", search_dir, NSE_DEPINFO);
+	sprintf(merge_file, NOCATGETS("%s/.tmp%s.%d"), search_dir, NSE_DEPINFO, getpid());
+	sprintf(lock_file, "%s/%s", search_dir, NSE_DEPINFO_LOCK);
+	err = file_lock(nse_depinfo_file, lock_file, &file_locked, 0);
+	if (err) {
+		if (warning_ptr != (void (*) (char *, ...)) NULL) {
+			(*warning_ptr)(catgets(libmksdmsi18n_catd, 1, 147, "Couldn't write to %s"), nse_depinfo_file);
+                      }
+		unlink(command_output_tmpfile);
+		return;
+	}
+	/* If .nse_depinfo file doesn't exist */
+	if ((nse_depinfo_fp = fopen(nse_depinfo_file, "r+")) == NULL) {
+		if (is_path) {
+			if ((nse_depinfo_fp = 
+			     fopen(nse_depinfo_file, "w")) == NULL) {
+				fprintf(stderr, catgets(libmksdmsi18n_catd, 1, 148, "Cannot open `%s' for writing\n"),
+				    nse_depinfo_file);
+				unlink(command_output_tmpfile);
+
+				unlink(lock_file);
+				return;
+			}
+			while (fgets(line, MAXPATHLEN+2, command_output_fp) 
+			       != NULL) {
+				fprintf(nse_depinfo_fp, "%s", line);
+			}
+			fclose(command_output_fp);
+		}
+		fclose(nse_depinfo_fp);
+		if (file_locked) {
+			unlink(lock_file);
+		}
+		unlink(command_output_tmpfile);
+		return;
+	}
+	if ((merge_fp = fopen(merge_file, "w")) == NULL) {
+		fprintf(stderr, catgets(libmksdmsi18n_catd, 1, 149, "Cannot open %s for writing\n"), merge_file);
+		if (file_locked) {
+			unlink(lock_file);
+		}
+		unlink(command_output_tmpfile);
+		return;
+	}
+	len = strlen(sfile);
+	while (fgets(line, MAXPATHLEN+2, nse_depinfo_fp) != NULL) {
+		if (strncmp(line, sfile, len) == 0 && line[len] == ':') {
+			while (fgets(buf, MAXPATHLEN+2, command_output_fp) 
+			       != NULL) {
+				if (is_path) {
+					fprintf(merge_fp, "%s", buf);
+					if (strcmp(line, buf)) {
+						/* changed */
+						changed = 1;
+					}
+				}
+				if (buf[strlen(buf)-1] == '\n') {
+					break;
+				}
+			}
+			if (changed || !is_path) {
+				while (fgets(line, MAXPATHLEN, nse_depinfo_fp)
+				       != NULL) {
+					fputs(line, merge_fp);
+				}
+				clean_up(nse_depinfo_fp, merge_fp, 
+					 nse_depinfo_file, merge_file, 0);
+			} else {
+				clean_up(nse_depinfo_fp, merge_fp, 
+					 nse_depinfo_file, merge_file, 1);
+			}
+			if (file_locked) {
+				unlink(lock_file);
+			}
+			unlink(command_output_tmpfile);
+			return;
+		} /* entry found */
+		fputs(line, merge_fp);
+	} 
+	/* Entry never found.  Add it if there is a search path */
+	if (is_path) {
+		while (fgets(line, MAXPATHLEN+2, command_output_fp) != NULL) {
+			fprintf(nse_depinfo_fp, "%s", line);
+		}
+	}
+	clean_up(nse_depinfo_fp, merge_fp, nse_depinfo_file, merge_file, 1);
+	if (file_locked) {
+		unlink(lock_file);
+	}
+}
+
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+} // extern "C"
+#endif
+
+static void
+report_dep(char *iflag, char *filename)
+{
+
+	if (command_output_fp == NULL) {
+		sprintf(command_output_tmpfile, 
+			NOCATGETS("%s/%s.%d.XXXXXX"), tmpdir, NSE_DEPINFO, getpid());
+		int fd = mkstemp(command_output_tmpfile);
+		if ((fd < 0) || (command_output_fp = fdopen(fd, "w")) == NULL) {
+			return;
+		}
+		if ((search_dir = getenv(NOCATGETS("NSE_DEP"))) == NULL) {
+			return;
+		}
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+		atexit(close_file);
+#else
+		on_exit(close_file, 0);
+#endif
+		strcpy(sfile, filename);
+		if (iflag == NULL || *iflag == '\0') {
+			return;
+		}
+		fprintf(command_output_fp, "%s:", sfile);
+	}
+	fprintf(command_output_fp, " ");
+	fprintf(command_output_fp, iflag);
+	if (iflag != NULL) {
+		is_path = 1;
+	}
+}
+
+void
+report_libdep(char *lib, char *flag)
+{
+	char		*ptr;
+	char		filename[MAXPATHLEN];
+	char		*p;
+
+	if ((p= getenv(SUNPRO_DEPENDENCIES)) == NULL) {
+		return;
+	}
+	ptr = strchr(p, ' ');
+	if(ptr) {
+		sprintf(filename, "%s-%s", ptr+1, flag);
+		is_path = 1;
+		report_dep(lib, filename);
+	}
+}
+
+void
+report_search_path(char *iflag)
+{
+	char		curdir[MAXPATHLEN];
+	char		*sdir;
+	char		*newiflag;
+	char		filename[MAXPATHLEN];
+	char		*p, *ptr;
+
+	if ((sdir = getenv(NOCATGETS("NSE_DEP"))) == NULL) {
+		return;
+	}
+	if ((p= getenv(SUNPRO_DEPENDENCIES)) == NULL) {
+		return;
+	}
+	ptr = strchr(p, ' ');
+	if( ! ptr ) {
+		return;
+	}
+	sprintf(filename, NOCATGETS("%s-CPP"), ptr+1);
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+	getcwd(curdir, sizeof(curdir));
+#else
+	getwd(curdir);
+#endif
+	if (strcmp(curdir, sdir) != 0 && strlen(iflag) > 2 && 
+	    iflag[2] != '/') {
+		/* Makefile must have had an "cd xx; cc ..." */
+		/* Modify the -I path to be relative to the cd */
+		newiflag = (char *)malloc(strlen(iflag) + strlen(curdir) + 2);
+		sprintf(newiflag, "-%c%s/%s", iflag[1], curdir, &iflag[2]);
+		report_dep(newiflag, filename);
+	} else {
+		report_dep(iflag, filename);
+	}
+}
+
+void
+report_dependency(register char *name)
+{
+	register char	*filename;
+	char		buffer[MAXPATHLEN+1];
+	register char	*p;
+	register char	*p2;
+	char		nse_depinfo_file[MAXPATHLEN];
+
+	if (report_file == NULL) {
+		if ((filename= getenv(SUNPRO_DEPENDENCIES)) == NULL) {
+			report_file = (FILE *)-1;
+			return;
+		}
+		if (strlen(filename) == 0) {
+			report_file = (FILE *)-1;
+			return;
+		}
+		(void)strcpy(buffer, name);
+		name = buffer;
+		p = strchr(filename, ' ');
+		if(p) {
+			*p= 0;
+		} else {
+			report_file = (FILE *)-1;
+			return;
+		}
+		if ((report_file= fopen(filename, "a")) == NULL) {
+			if ((report_file= fopen(filename, "w")) == NULL) {
+				report_file= (FILE *)-1;
+				return;
+			}
+		}
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+		atexit(close_report_file);
+#else
+		(void)on_exit(close_report_file, (char *)report_file);
+#endif
+		if ((p2= strchr(p+1, ' ')) != NULL)
+			*p2= 0;
+		target_being_reported_for= (char *)malloc((unsigned)(strlen(p+1)+1));
+		(void)strcpy(target_being_reported_for, p+1);
+		(void)fputs(p+1, report_file);
+		(void)fputs(":", report_file);
+		*p= ' ';
+		if (p2 != NULL)
+			*p2= ' ';
+	}
+	if (report_file == (FILE *)-1)
+		return;
+	(void)fputs(name, report_file);
+	(void)fputs(" ", report_file);
+}
+
+#ifdef MAKE_IT
+void
+make_it(filename)
+	register char	*filename;
+{
+	register char	*command;
+	register char	*argv[6];
+	register int	pid;
+	union wait	foo;
+
+	if (getenv(SUNPRO_DEPENDENCIES) == NULL) return;
+	command= alloca(strlen(filename)+32);
+	(void)sprintf(command, NOCATGETS("make %s\n"), filename);
+	switch (pid= fork()) {
+		case 0: /* child */
+			argv[0]= NOCATGETS("csh");
+			argv[1]= NOCATGETS("-c");
+			argv[2]= command;
+			argv[3]= 0;			
+			(void)dup2(2, 1);
+			execve(NOCATGETS("/bin/sh"), argv, environ);
+			perror(NOCATGETS("execve error"));
+			exit(1);
+		case -1: /* error */
+			perror(NOCATGETS("fork error"));
+		default: /* parent */
+			while (wait(&foo) != pid);};
+}
+#endif
+
--- /dev/null	2015-05-20 11:04:26.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/src/rmdir.cc	2015-05-20 11:04:26.862022694 -0400
@@ -0,0 +1,48 @@
+/*
+ * 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 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)rmdir.cc 1.4 06/12/12
+ */
+
+#pragma	ident	"@(#)rmdir.cc	1.4	06/12/12"
+
+#include <unistd.h>
+
+extern int rmdir(const char *path);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int	rmdir_thunk(char *path)
+{
+	vroot_result= rmdir(path);
+	return(vroot_result == 0);
+}
+
+int	rmdir_vroot(char *path, pathpt vroot_path, pathpt vroot_vroot)
+{
+	translate_with_thunk(path, rmdir_thunk, vroot_path, vroot_vroot, rw_read);
+	return(vroot_result);
+}
--- /dev/null	2015-05-20 11:04:27.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/src/setenv.cc	2015-05-20 11:04:27.074938645 -0400
@@ -0,0 +1,65 @@
+/*
+ * 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 1994 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)setenv.cc 1.6 06/12/12
+ */
+
+#pragma	ident	"@(#)setenv.cc	1.6	06/12/12"
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+extern	char	**environ;
+
+static	short	setenv_made_new_vector= 0;
+
+char *setenv(char *name, char *value)
+{	char *p= NULL, **q;
+	int length= 0, vl;
+
+	if ((p= getenv(name)) == NULL) {	/* Allocate new vector */
+		for (q= environ; *q != NULL; q++, length++);
+		q= (char **)malloc((unsigned)(sizeof(char *)*(length+2)));
+                memcpy(((char *)q)+sizeof(char *), (char *)environ, sizeof(char *)*(length+1));
+		if (setenv_made_new_vector++)
+			free((char *)environ);
+		length= strlen(name);
+		environ= q;}
+	else { /* Find old slot */
+		length= strlen(name);
+		for (q= environ; *q != NULL; q++)
+			if (!strncmp(*q, name, length))
+				break;};
+	vl= strlen(value);
+	if (!p || (length+vl+1 > strlen(p)))
+		*q= p= (char *) malloc((unsigned)(length+vl+2));
+	else
+		p= *q;
+	(void)strcpy(p, name); p+= length;
+	*p++= '=';
+	(void)strcpy(p, value);
+	return(value);
+}
--- /dev/null	2015-05-20 11:04:27.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/src/stat.cc	2015-05-20 11:04:27.494374741 -0400
@@ -0,0 +1,50 @@
+/*
+ * 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 1998 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)stat.cc 1.6 06/12/12
+ */
+
+#pragma	ident	"@(#)stat.cc	1.6	06/12/12"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+extern int stat(const char *path, struct stat *buf);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int	stat_thunk(char *path)
+{
+	vroot_result= stat(path, vroot_args.stat.buffer);
+	return(vroot_result == 0);
+}
+
+int	stat_vroot(char *path, struct stat *buffer, pathpt vroot_path, pathpt vroot_vroot)
+{
+	vroot_args.stat.buffer= buffer;
+	translate_with_thunk(path, stat_thunk, vroot_path, vroot_vroot, rw_read);
+	return(vroot_result);
+}
--- /dev/null	2015-05-20 11:04:27.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/src/statfs.cc	2015-05-20 11:04:27.928098665 -0400
@@ -0,0 +1,49 @@
+/*
+ * 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 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)statfs.cc 1.5 06/12/12
+ */
+
+#pragma	ident	"@(#)statfs.cc	1.5	06/12/12"
+
+#ifndef SUN5_0
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+#include <sys/vfs.h>
+
+static int	statfs_thunk(char *path)
+{
+	vroot_result= statfs(path, vroot_args.statfs.buffer);
+	return(vroot_result == 0);
+}
+
+int	statfs_vroot(char *path, struct statfs *buffer, pathpt vroot_path, pathpt vroot_vroot)
+{
+	vroot_args.statfs.buffer= buffer;
+	translate_with_thunk(path, statfs_thunk, vroot_path, vroot_vroot, rw_read);
+	return(vroot_result);
+}
+#endif
--- /dev/null	2015-05-20 11:04:28.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/src/truncate.cc	2015-05-20 11:04:28.723767876 -0400
@@ -0,0 +1,49 @@
+/*
+ * 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 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)truncate.cc 1.4 06/12/12
+ */
+
+#pragma	ident	"@(#)truncate.cc	1.4	06/12/12"
+
+#include <unistd.h>
+
+extern int truncate(const char *path, off_t length);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int	truncate_thunk(char *path)
+{
+	vroot_result= truncate(path, vroot_args.truncate.length);
+	return(vroot_result == 0);
+}
+
+int	truncate_vroot(char *path, int length, pathpt vroot_path, pathpt vroot_vroot)
+{
+	vroot_args.truncate.length= length;
+	translate_with_thunk(path, truncate_thunk, vroot_path, vroot_vroot, rw_read);
+	return(vroot_result);
+}
--- /dev/null	2015-05-20 11:04:29.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/src/unlink.cc	2015-05-20 11:04:29.006772894 -0400
@@ -0,0 +1,48 @@
+/*
+ * 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 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)unlink.cc 1.4 06/12/12
+ */
+
+#pragma	ident	"@(#)unlink.cc	1.4	06/12/12"
+
+#include <unistd.h>
+
+extern int unlink(const char *path);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int	unlink_thunk(char *path)
+{
+	vroot_result= unlink(path);
+	return(vroot_result == 0);
+}
+
+int	unlink_vroot(char *path, pathpt vroot_path, pathpt vroot_vroot)
+{
+	translate_with_thunk(path, unlink_thunk, vroot_path, vroot_vroot, rw_read);
+	return(vroot_result);
+}
--- /dev/null	2015-05-20 11:04:29.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/src/unmount.cc	2015-05-20 11:04:29.195531367 -0400
@@ -0,0 +1,48 @@
+/*
+ * 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 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)unmount.cc 1.5 06/12/12
+ */
+
+#pragma	ident	"@(#)unmount.cc	1.5	06/12/12"
+
+#ifndef SUN5_0
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+extern int	unmount(char *name);
+
+static int	unmount_thunk(char *path)
+{
+	vroot_result= unmount(path);
+	return(vroot_result == 0);
+}
+
+int	unmount_vroot(char *path, pathpt vroot_path, pathpt vroot_vroot)
+{
+	translate_with_thunk(path, unmount_thunk, vroot_path, vroot_vroot, rw_read);
+	return(vroot_result);
+}
+#endif
--- /dev/null	2015-05-20 11:04:29.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/src/utimes.cc	2015-05-20 11:04:29.384556887 -0400
@@ -0,0 +1,50 @@
+/*
+ * 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 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)utimes.cc 1.4 06/12/12
+ */
+
+#pragma	ident	"@(#)utimes.cc	1.4	06/12/12"
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+extern int utimes(char *file, struct timeval *tvp);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int	utimes_thunk(char *path)
+{
+	vroot_result= utimes(path, vroot_args.utimes.time);
+	return(vroot_result == 0);
+}
+
+int	utimes_vroot(char *path, struct timeval *time, pathpt vroot_path, pathpt vroot_vroot)
+{
+	vroot_args.utimes.time= time;
+	translate_with_thunk(path, utimes_thunk, vroot_path, vroot_vroot, rw_read);
+	return(vroot_result);
+}
--- /dev/null	2015-05-20 11:04:29.000000000 -0400
+++ new/usr/src/cmd/make/lib/vroot/src/vroot.cc	2015-05-20 11:04:29.573662130 -0400
@@ -0,0 +1,344 @@
+/*
+ * 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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)vroot.cc 1.11 06/12/12
+ */
+
+#pragma	ident	"@(#)vroot.cc	1.11	06/12/12"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+#include <string.h>
+#include <sys/param.h>
+#include <sys/file.h>
+
+#include <avo/intl.h>	/* for NOCATGETS */
+
+typedef struct {
+	short		init;
+	pathpt		vector;
+	char		*env_var;
+} vroot_patht;
+
+typedef struct {
+	vroot_patht	vroot;
+	vroot_patht	path;
+	char		full_path[MAXPATHLEN+1];
+	char		*vroot_start;
+	char		*path_start;
+	char		*filename_start;
+	int		scan_vroot_first;
+	int		cpp_style_path;
+} vroot_datat, *vroot_datapt;
+
+static vroot_datat	vroot_data= {
+	{ 0, NULL, NOCATGETS("VIRTUAL_ROOT")},
+	{ 0, NULL, NOCATGETS("PATH")},
+	"", NULL, NULL, NULL, 0, 1};
+
+void
+add_dir_to_path(register char *path, register pathpt *pointer, register int position)
+{
+	register int		size= 0;
+	register int		length;
+	register char		*name;
+	register pathcellpt	p;
+	pathpt			new_path;
+
+	if (*pointer != NULL) {
+		for (p= &((*pointer)[0]); p->path != NULL; p++, size++);
+		if (position < 0)
+			position= size;}
+	else
+		if (position < 0)
+			position= 0;
+	if (position >= size) {
+		new_path= (pathpt)calloc((unsigned)(position+2), sizeof(pathcellt));
+		if (*pointer != NULL) {
+			memcpy((char *)new_path,(char *)(*pointer),  size*sizeof(pathcellt));
+			free((char *)(*pointer));};
+		*pointer= new_path;};
+	length= strlen(path);
+	name= (char *)malloc((unsigned)(length+1));
+	(void)strcpy(name, path);
+	if ((*pointer)[position].path != NULL)
+		free((*pointer)[position].path);
+	(*pointer)[position].path= name;
+	(*pointer)[position].length= length;
+}
+
+pathpt
+parse_path_string(register char *string, register int remove_slash)
+{
+	register char		*p;
+	pathpt			result= NULL;
+
+	if (string != NULL)
+		for (; 1; string= p+1) {
+			if (p= strchr(string, ':')) *p= 0;
+			if ((remove_slash == 1) && !strcmp(string, "/"))
+				add_dir_to_path("", &result, -1);
+			else
+				add_dir_to_path(string, &result, -1);
+			if (p) *p= ':';
+			else return(result);};
+	return((pathpt)NULL);
+}
+
+char *
+get_vroot_name(void)
+{
+	return(vroot_data.vroot.env_var);
+}
+
+char *
+get_path_name(void)
+{
+	return(vroot_data.path.env_var);
+}
+
+void
+flush_path_cache(void)
+{
+	vroot_data.path.init= 0;
+}
+
+void
+flush_vroot_cache(void)
+{
+	vroot_data.vroot.init= 0;
+}
+
+void
+scan_path_first(void)
+{
+	vroot_data.scan_vroot_first= 0;
+}
+
+void
+scan_vroot_first(void)
+{
+	vroot_data.scan_vroot_first= 1;
+}
+
+void
+set_path_style(int style)
+{
+	vroot_data.cpp_style_path= style;
+}
+
+char *
+get_vroot_path(register char **vroot, register char **path, register char **filename)
+{
+	if (vroot != NULL) {
+		if ((*vroot= vroot_data.vroot_start) == NULL)
+		if ((*vroot= vroot_data.path_start) == NULL)
+		*vroot= vroot_data.filename_start;};
+	if (path != NULL) {
+		if ((*path= vroot_data.path_start) == NULL)
+		*path= vroot_data.filename_start;};
+	if (filename != NULL)
+		*filename= vroot_data.filename_start;
+	return(vroot_data.full_path);
+}
+
+void
+translate_with_thunk(register char *filename, int (*thunk) (char *), pathpt path_vector, pathpt vroot_vector, rwt rw)
+{
+	register pathcellt	*vp;
+	pathcellt		*pp;
+	register pathcellt	*pp1;
+	register char		*p;
+	int			flags[256];
+
+/* Setup path to use */
+	if (rw == rw_write)
+		pp1= NULL;		/* Do not use path when writing */
+	else {
+		if (path_vector == VROOT_DEFAULT) {
+			if (!vroot_data.path.init) {
+				vroot_data.path.init= 1;
+				vroot_data.path.vector= parse_path_string(getenv(vroot_data.path.env_var), 0);};
+			path_vector= vroot_data.path.vector;};
+		pp1= path_vector == NULL ? NULL : &(path_vector)[0];};
+
+/* Setup vroot to use */
+	if (vroot_vector == VROOT_DEFAULT) {
+		if (!vroot_data.vroot.init) {
+			vroot_data.vroot.init= 1;
+			vroot_data.vroot.vector= parse_path_string(getenv(vroot_data.vroot.env_var), 1);};
+		vroot_vector= vroot_data.vroot.vector;};
+	vp= vroot_vector == NULL ? NULL : &(vroot_vector)[0];
+
+/* Setup to remember pieces */
+	vroot_data.vroot_start= NULL;
+	vroot_data.path_start= NULL;
+	vroot_data.filename_start= NULL;
+
+	int flen = strlen(filename);
+	if(flen >= MAXPATHLEN) {
+		errno = ENAMETOOLONG;
+		return;
+	}
+
+	switch ((vp ?1:0) + (pp1 ? 2:0)) {
+	    case 0:	/* No path. No vroot. */
+	    use_name:
+		(void)strcpy(vroot_data.full_path, filename);
+		vroot_data.filename_start= vroot_data.full_path;
+		(void)(*thunk)(vroot_data.full_path);
+		return;
+	    case 1:	/* No path. Vroot */
+		if (filename[0] != '/') goto use_name;
+		for (; vp->path != NULL; vp++) {
+			if((1 + flen + vp->length) >= MAXPATHLEN) {
+				errno = ENAMETOOLONG;
+				continue;
+			}
+			p= vroot_data.full_path;
+			(void)strcpy(vroot_data.vroot_start= p, vp->path);
+			p+= vp->length;
+			(void)strcpy(vroot_data.filename_start= p, filename);
+			if ((*thunk)(vroot_data.full_path)) return;};
+		(void)strcpy(vroot_data.full_path, filename);
+		return;
+	    case 2:	/* Path. No vroot. */
+		if (vroot_data.cpp_style_path) {
+			if (filename[0] == '/') goto use_name;
+		} else {
+			if (strchr(filename, '/') != NULL) goto use_name;
+		};
+		for (; pp1->path != NULL; pp1++) {
+			p= vroot_data.full_path;
+			if((1 + flen + pp1->length) >= MAXPATHLEN) {
+				errno = ENAMETOOLONG;
+				continue;
+			}
+			if (vroot_data.cpp_style_path) {
+				(void)strcpy(vroot_data.path_start= p, pp1->path);
+				p+= pp1->length;
+				*p++= '/';
+			} else {
+				if (pp1->length != 0) {
+					(void)strcpy(vroot_data.path_start= p,
+					    pp1->path);
+					p+= pp1->length;
+					*p++= '/';
+				};
+			};
+			(void)strcpy(vroot_data.filename_start= p, filename);
+			if ((*thunk)(vroot_data.full_path)) return;};
+		(void)strcpy(vroot_data.full_path, filename);
+		return;
+	    case 3: {	/* Path. Vroot. */
+			int *rel_path, path_len= 1;
+		if (vroot_data.scan_vroot_first == 0) {
+			for (pp= pp1; pp->path != NULL; pp++) path_len++;
+			rel_path= flags;
+			for (path_len-= 2; path_len >= 0; path_len--) rel_path[path_len]= 0;
+			for (; vp->path != NULL; vp++)
+				for (pp= pp1, path_len= 0; pp->path != NULL; pp++, path_len++) {
+					int len = 0;
+					if (rel_path[path_len] == 1) continue;
+					if (pp->path[0] != '/') rel_path[path_len]= 1;
+					p= vroot_data.full_path;
+					if ((filename[0] == '/') || (pp->path[0] == '/')) {
+						if(vp->length >= MAXPATHLEN) {
+							errno = ENAMETOOLONG;
+							continue;
+						}
+						(void)strcpy(vroot_data.vroot_start= p, vp->path); p+= vp->length;
+						len += vp->length;
+					};
+					if (vroot_data.cpp_style_path) {
+						if (filename[0] != '/') {
+							if(1 + len + pp->length >= MAXPATHLEN) {
+								errno = ENAMETOOLONG;
+								continue;
+							}
+							(void)strcpy(vroot_data.path_start= p, pp->path); p+= pp->length;
+							*p++= '/';
+							len += 1 + pp->length;
+						};
+					} else {
+						if (strchr(filename, '/') == NULL) {
+							if (pp->length != 0) {
+								if(1 + len + pp->length >= MAXPATHLEN) {
+									errno = ENAMETOOLONG;
+									continue;
+								}
+								(void)strcpy(vroot_data.path_start= p,
+								    pp->path);
+								p+= pp->length;
+								*p++= '/';
+								len += 1 + pp->length;
+							}
+						}
+					};
+					(void)strcpy(vroot_data.filename_start= p, filename);
+					if ((*thunk)(vroot_data.full_path)) return;};}
+		else { pathcellt *vp1= vp;
+			for (pp= pp1, path_len= 0; pp->path != NULL; pp++, path_len++)
+				for (vp= vp1; vp->path != NULL; vp++) {
+					int len = 0;
+					p= vroot_data.full_path;
+					if ((filename[0] == '/') || (pp->path[0] == '/')) {
+						if(vp->length >= MAXPATHLEN) {
+							errno = ENAMETOOLONG;
+							continue;
+						}
+						(void)strcpy(vroot_data.vroot_start= p, vp->path); p+= vp->length;
+						len += vp->length;
+					}
+					if (vroot_data.cpp_style_path) {
+						if (filename[0] != '/') {
+							if(1 + len + pp->length >= MAXPATHLEN) {
+								errno = ENAMETOOLONG;
+								continue;
+							}
+							(void)strcpy(vroot_data.path_start= p, pp->path); p+= pp->length;
+							*p++= '/';
+							len += 1 + pp->length;
+						}
+					} else {
+						if (strchr(filename, '/') == NULL) {
+							if(1 + len + pp->length >= MAXPATHLEN) {
+								errno = ENAMETOOLONG;
+								continue;
+							}
+							(void)strcpy(vroot_data.path_start= p, pp->path); p+= pp->length;
+							*p++= '/';
+							len += 1 + pp->length;
+						}
+					}
+					(void)strcpy(vroot_data.filename_start= p, filename);
+					if ((*thunk)(vroot_data.full_path)) return;};};
+		(void)strcpy(vroot_data.full_path, filename);
+		return;};};
+}
