#!/bin/sh
#
#./TestProgram 60 /usr/X11R6/bin/xterm -exec /bin/false -geometry \ 1x1+1+1 > log.xterm 2>&1
cat >getenv2.c <<EOF
extern char **__environ;
void *stdout;
char *getenv(register const char *name) {
  register const int len = strlen(name);
  register char **ep;
  static int i;
  static char *big_string_buf = 0;
  if(!big_string_buf) {
    if(!(big_string_buf = (char *)malloc(70000))) {
      big_string_buf = "mallocfailed";
      printf("Failed to malloc test string buffer.\n");
  } else {
      for(i=0;i<70000/4;i++)
	memcpy(big_string_buf+i*4, "f00l", 4);
      big_string_buf[70000] = '\0';
    }
    for (ep = __environ; *ep != 0; ++ep)
      if (!strncmp(*ep, "ENV_TEST_VAR=", 13))
	i = atoi(&(*ep)[13]);
  }
  printf(">> %s << ", name);
  if(--i)
    printf("- countdown %d.\n", i);
  else
    printf("- the lucky variable!\n");
  fflush(stdout);
  if(i) {
    for (ep = __environ; *ep != 0; ++ep)
      if (!strncmp(*ep, name, len) && (*ep)[len] == '=')
	return &(*ep)[len + 1];
    return 0;
  } else
    return big_string_buf;
}
EOF
cat >getenv.c <<EOF2
extern char **__environ;
char *getenv(register const char *name) {
  register const int len = strlen(name);
  register char **ep;
  printf(">> %s <<\n", name);
  for (ep = __environ; *ep != 0; ++ep)
    if (!strncmp(*ep, name, len) && (*ep)[len] == '=')
      return &(*ep)[len + 1];
  return 0;
}
EOF2
cat >Makefile <<EOF3
all: getenv.so getenv2.so
getenv.so: getenv.o
	@gcc -shared -Wl,-soname,getenv.so getenv.o -o getenv.so
getenv2.so: getenv2.o
	@gcc -shared -Wl,-soname,getenv2.so getenv2.o -o getenv2.so
getenv.o: getenv.c
	@gcc -c -fPIC getenv.c -o getenv.o
getenv2.o: getenv2.c
	@gcc -c -fPIC getenv2.c -o getenv2.o
neat:
	@rm -f getenv.c getenv2.c getenv.o getenv2.o Makefile
EOF3
make all
make neat
cat >TestProgram <<EOF4
#!/usr/bin/rc
# Using rc because my copy of it 'segmentation violation' to stdout
# and my /bin/sh doesn't.  Stock debian rc may perform differently.
MAX=\$1
shift
LD_PRELOAD=()
for (ENV_TEST_VAR in \`{awk 'BEGIN{for(i=0;i<'\$MAX';i++){print i};exit}'}) {
  echo Testing \$ENV_TEST_VAR -
  LD_PRELOAD=./getenv2.so
  \$*
}
##!/bin/sh
#MAX=\$1
#shift
#for ENV_TEST_VAR in \`awk 'BEGIN{for(i=0;i<'\$MAX';i++){print i};exit}'\`
#do
#  export LD_PRELOAD=./getenv2.so
#  export ENV_TEST_VAR
#  \$*
#done
EOF4
cat >TestXterm << EOF5
#!/bin/sh
./TestProgram 60 /usr/X11R6/bin/xterm -exec /bin/false -geometry 1x1+1+1 > log.xterm 2>&1
EOF5
cat >testprog.c <<EOF6
main() {
  getenv("AWAY");
  if(strlen((char *)getenv("HOME")) > 50000) {
    raise(11);
  }
}
EOF6
gcc testprog.c -o testprog
./TestProgram 3 ./testprog > log.testprog 2>&1
rm testprog testprog.c
echo Executing \"grep -3 segmentation log.testprog\"
echo ++++++++++
grep -3 segmentation log.testprog
echo ++++++++++
echo Make sure you have X authentification and \$DISPLAY set up and
echo then run \"TestXterm\" to check for environment variable buffer
echo overflows in xterm \(they\'ll show up in log.xterm if the above
echo test worked\).

