#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  Makefile README virtlaunch vroot.c
# Wrapped by casper@mail on Fri Apr 21 17:54:50 1995
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(89 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
XCC=cc
XCFLAGS=-K pic -O
X
X#CC=gcc
X#CFLAGS=-fpic -O
X
Xvroot.so: vroot.o
X	ld -G -o $@ vroot.o
END_OF_FILE
if test 89 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(1965 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XHow to compile SunOS executables under Solaris 2.x with the
XSunOS 4.1.x compilers.
X
XWith this README you should get:
X
X	- vroot.c
X	- Makefile
X	- virtlaunch
X
XMake the vroot.so file.
XIf you have gcc, you'll need to edit the Makefile and change CFLAGS.
X
XDetermine a directory in which you will load part of SunOS 4.x
XWe'll call this directory $SunOS4_Root.
X
XInstall /usr from a SunOS 4.x machine in $SunOS4_Root/usr
XYou don't need everything, you do need:
X	- /usr/include
X	- /usr/bin/{ld,cc,as,ar,ranlib}
X	  add tools as you see fit: lex, yacc, nm, size, make
X	- /usr/lib
X	  - all libraries, lang_info, symlinks to libraries.
X	  *note* make sure that you preserver the mtime on the archive
X	  libraries (lib*.a, lib*.sa.*)
X	- /usr/kvm (but see below about kernel architectures)
X
X	% cp vroot.so $SunOS4_Root
X	% cp virtlaunch $SunOS4_Root/usr/bin
X	% cd $SunOS4_Root
X	% ln -s usr/bin usr/lib .
X
X	% cd $SunOS4_Root/usr/bin
X	The following steps can be repeated for lex, make, yacc and possibly
X	as.
X	Normally, you don't need to do this for as as it never uses include
X	files. Wrapping an executable with a script does slow things down.
X	% mv cc cc.bin
X	% ln -s virtlaunch cc
X	% mv ld ld.bin
X	% ln -s virtlaunch ld
X
XWhen cross compiling, simply prepend your $PATH with $SunOS4_Root/usr/bin
Xand off you go.
X
XCross compiling for different kernel architectures is possible too.
X
XRemove the  $SunOS4_Root/usr/kvm directory
X
X	cd $SunOS4_Root
X	mkdir -p sun4{c,m}/usr/{include,lib}
X	ln -s usr/lib sun4/lib
X	ln -s ../../../usr/include/sun4 sun4/usr/include/machine
X	ln -s usr/lib sun4c/lib
X	ln -s ../../../usr/include/sun4c sun4c/usr/include/machine
X	ln -s usr/lib sun4m/lib
X	ln -s ../../../usr/include/sun4m sun4m/usr/include/machine
X
XAnd copy the libkvm* files to sun4{,c,m}/usr/lib
X
XThe environment variable VROOT_KARCH determines the Kernel architecture
Xof the resulting executable.
X
XThe environment variable VROOT_TRACE will cause some trace output
Xto appear on stderr.
X
XCasper
END_OF_FILE
if test 1965 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'virtlaunch' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'virtlaunch'\"
else
echo shar: Extracting \"'virtlaunch'\" \(1053 characters\)
sed "s/^X//" >'virtlaunch' <<'END_OF_FILE'
X#!/sbin/sh
X#
X# Virtual rooted Cross compilation 5.2 -> 4.1.x tool.
X# For cc, VIRTUAL_ROOT works fine in most cases.
X# There is on exeception: cc needs the file /usr/lib/lang_info
X# But cc must use VIRTUAL_ROOT, 'cause we don't want any
X# of the /usr/include files used.
X# For ld, it doesn't works because it breaks the library search
X# path that's included in the executable.
X#
X# Casper Dik, 1993
X#
X
Xunset LD_PRELOAD
X# Figure out the envronment.
Xprogram=`basename $0`
Xdir=`dirname $0`
X# Strip trailing bin or lib
Xdir=`dirname $dir`
Xcase "$dir" in
X	*/usr) dir=`dirname "$dir"`;;
Xesac
X: ${VROOT_KARCH=sun4m}
X
Xif [ -d ${dir}/${VROOT_KARCH} ]
Xthen
X    __VPATH=${dir}:${dir}/${VROOT_KARCH}
Xelse
X    __VPATH=${dir}
Xfi
X
Xexport LD_PRELOAD
X# Not sure about as, other branch may be needed for make and others as well.
Xif [ "$program" != cc -a "$program" != as ]
Xthen
X    VROOT_PATH="$__VPATH"
X    unset VIRTUAL_ROOT
Xelse
X    VIRTUAL_ROOT="$__VPATH"
X    VROOT_PATH="$dir"
Xfi
XLD_PRELOAD="${dir}/vroot.so" 
Xexport LD_PRELOAD VROOT_PATH VIRTUAL_ROOT
Xexec $0.bin "$@"
END_OF_FILE
if test 1053 -ne `wc -c <'virtlaunch'`; then
    echo shar: \"'virtlaunch'\" unpacked with wrong size!
fi
chmod +x 'virtlaunch'
# end of 'virtlaunch'
fi
if test -f 'vroot.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'vroot.c'\"
else
echo shar: Extracting \"'vroot.c'\" \(4527 characters\)
sed "s/^X//" >'vroot.c' <<'END_OF_FILE'
X/*
X * Preload library that intercepts calls to access, open and execve.
X * This library can be used to let certain programs search for
X * certain files in a ``virtual rooted'' environment.
X *
X * It has been tailored for the use of SunOS 4.x cc/ld running in BCP
X * mode on Solaris.
X *
X * Note that one aspect of this breaks: if you have multiple entries
X * in VROOT_PATH, only the first directory found is opened.
X * Since ld uses readdir to find certain libraries, that first directory
X * must contain dummy entries for libraries found further along the
X * VROOT_PATH. These dummy entries must be symlinks pointing nowhere.
X *
X * Currently, normal Solaris executables will not search the VROOT_PATH.
X * Perhaps they should.
X *
X * Casper Dik, 1993
X * 
X */
X#include <sys/types.h>
X#include <sys/param.h>
X#include <sys/syscall.h>
X#include <stdio.h>
X#include <fcntl.h>
X#include <stdarg.h>
X#include <stdlib.h>
X#include <unistd.h>
X#include <string.h>
X#include <dlfcn.h>
X
Xstatic FILE *vroot_trace;
X
Xstatic char **paths;
Xstatic int bcp_mode;
X#define SAFESPACE 4
Xstatic char *_xpaths[SAFESPACE];
X
X/*
X * This is called when the library is first loaded
X */
X_init()
X{
X    char *vroot;
X    void *handle = dlopen(0, RTLD_LAZY);
X
X    bcp_mode = dlsym(handle, "bc_open") != 0;
X
X    dlclose(handle);
X
X    vroot = getenv("VROOT_PATH");
X    if (vroot) {
X	int cnt = 0;
X	char *p = vroot;
X	while (p = strchr(p,':'))
X	    cnt++,p++;
X	cnt += 2;
X	if (cnt <= SAFESPACE)
X	    paths =  _xpaths;
X	else
X	    paths = malloc(sizeof(char*)*cnt);
X	if (cnt != 2)
X	    vroot = strdup(vroot);
X	for (p = vroot, cnt = 0;  vroot ; ) {
X	    p = strchr(vroot,':');
X	    paths[cnt++] = vroot;
X	    if (p)
X		*p++ = '\0';
X	    vroot = p;
X	}
X
X	paths[cnt] = 0;
X	/*
X	 * We don't know which print we'll call but if we use stderr
X	 * here, we may end up with incompatible functions/FILE *
X	 */
X	if (getenv("VROOT_TRACE")) {
X	    vroot_trace = fdopen(2,"a");
X	    fprintf(vroot_trace, "vroot.so: %s executable\n",
X			bcp_mode ? "bcp" : "normal");
X	}
X    }
X}
X
Xstatic const char *
Xvrootexpand(const char *file, char *buf, const char* name, int amode)
X{
X    char **p;
X    char *vr = getenv("VROOT_PATH");
X    int len;
X
X    /*
X     * Unexpand absolute file names not starting with /usr. /lib, /bin or
X     * /sys.  VROOT_PATH is just too aggressive
X     */
X    if (vr) {
X	char *ind = strchr(vr,':');
X	if (ind)
X	    len = ind - vr;
X	else
X	    len = strlen(vr);
X
X	if (strncmp(vr,file,len) == 0) {
X	    if (strncmp(file+len,"/usr",4) != 0 &&
X		strncmp(file+len,"/sys",4) != 0 &&
X		strncmp(file+len,"/bin",4) != 0 &&
X		strncmp(file+len,"/lib",4) != 0 &&
X		_access(file+len,amode) == 0)
X		return file+len;
X	}
X    }
X
X    /* no VROOT_PATH or not a file with an absolute pathname */
X    if (bcp_mode == 0 || paths == 0 || *file != '/')
X	return file;
X
X    /* already expanded */
X    for (p = paths; *p; p++)
X	if (strncmp(*p, file, strlen(*p)) == 0)
X	    return file;
X
X    for (p = paths; *p; p++) {
X	strcpy(buf,*p);
X	strcat(buf,file);
X	if (_access(buf,amode) == 0) {
X	    if (vroot_trace)
X		fprintf(vroot_trace,"%s: %s\n", name, buf);
X	    return buf;
X	}
X    }
X    if (vroot_trace)
X	fprintf(vroot_trace,"%s: not found: %s\n", name, file);
X    return file;
X}
X
X/* Either BCP open or Solaris 2.x open. We must call the right syscall
X * function. syscall() is either the SunOS 4.1.x syscall (BCP mode)
X * or Solaris syscall (Solaris executable).
X * _syscall is always the Solaris 2.x syscall() function
X */
Xint
Xopen(const char *arg, int oflag, ...)
X{
X    va_list ap;
X    mode_t mode;
X    char pathbuf[MAXPATHLEN];
X    const char *p;
X
X    va_start(ap,oflag);
X    mode = va_arg(ap,int);
X    va_end(ap);
X    /* only search when reading */
X    p = oflag ? arg : vrootexpand(arg, pathbuf, "open", R_OK);
X    /* Fortunately, SYS_open is 5 in SunOS 4.x and Solaris 2.x */
X    return syscall(SYS_open, p, oflag, mode);
X}
X
X#if 0
X/* Solaris 2.x open */
Xint _open (const char *arg, int oflag, int mode)
X{
X    char pathbuf[MAXPATHLEN];
X    const char *p = oflag ? arg : vrootexpand(arg, pathbuf, "_open", R_OK);
X    return _syscall(SYS_open, p, oflag, mode);
X}
X#endif
X
Xint
Xexecve(const char *path, char *const argv[], char *const envp[])
X{
X    char buf[MAXPATHLEN];
X    return _execve(vrootexpand(path, buf,"execve", X_OK), argv, envp);
X}
X
Xint access(const char *path, int flag)
X{
X    char buf[MAXPATHLEN];
X    return _access(vrootexpand(path, buf, "access", flag), flag);
X}
X
Xint stat(const char *path, void * sbuf)
X{
X    char buf[MAXPATHLEN];
X    return bc_stat(vrootexpand(path, buf, "stat", 0), sbuf);
X}
END_OF_FILE
if test 4527 -ne `wc -c <'vroot.c'`; then
    echo shar: \"'vroot.c'\" unpacked with wrong size!
fi
# end of 'vroot.c'
fi
echo shar: End of shell archive.
exit 0
