about summary refs log tree commit diff
path: root/buildtools
diff options
context:
space:
mode:
Diffstat (limited to 'buildtools')
-rw-r--r--buildtools/Makefile46
-rw-r--r--buildtools/Makefile.manpage366
-rw-r--r--buildtools/README.pkg144
-rw-r--r--buildtools/config_template52
-rwxr-xr-xbuildtools/configure.pl2111
-rwxr-xr-xbuildtools/empty_depend19
-rwxr-xr-xbuildtools/endiangenbin0 -> 14005 bytes
-rw-r--r--buildtools/endiangen.c97
-rwxr-xr-xbuildtools/install.sh255
-rwxr-xr-xbuildtools/installnetpbm.pl919
-rwxr-xr-xbuildtools/installosf31
-rwxr-xr-xbuildtools/liboptbin0 -> 18008 bytes
-rw-r--r--buildtools/libopt.c541
-rwxr-xr-xbuildtools/make_merge.sh12
-rwxr-xr-xbuildtools/makecat18
-rwxr-xr-xbuildtools/makeman333
-rwxr-xr-xbuildtools/makepointerman91
-rwxr-xr-xbuildtools/mkinstalldirs41
-rwxr-xr-xbuildtools/stamp-date23
-rwxr-xr-xbuildtools/typegenbin0 -> 14159 bytes
-rw-r--r--buildtools/typegen.c113
21 files changed, 5212 insertions, 0 deletions
diff --git a/buildtools/Makefile b/buildtools/Makefile
new file mode 100644
index 00000000..63da1adf
--- /dev/null
+++ b/buildtools/Makefile
@@ -0,0 +1,46 @@
+ifeq ($(SRCDIR)x,x)
+  SRCDIR = $(CURDIR)/..
+  BUILDDIR = $(SRCDIR)
+endif
+SUBDIR = buildtools
+VPATH = .:$(SRCDIR)/$(SUBDIR)
+include $(BUILDDIR)/Makefile.config
+
+MERGE_OBJECTS =
+
+# These are programs that are used by the make files:
+PROGS = libopt typegen endiangen
+
+all: $(PROGS)
+
+BINARIES =
+SCRIPTS =
+
+OMIT_BUILDTOOL_RULE = 1
+include $(SRCDIR)/Makefile.common
+
+ifdef DLLVER
+STRIP_DLL_VERSION=-DDLLVERSTR="\"$(DLLVER)\""
+endif
+
+ifeq ($(LINKER_CAN_DO_EXPLICIT_LIBRARY),Y)
+EXPLICIT=-DEXPLICIT
+endif
+
+libopt.o: libopt.c
+	$(CC_FOR_BUILD) -c $(CFLAGS_FOR_BUILD) \
+	  -DSHLIBPREFIXLIST="\"$(SHLIBPREFIXLIST)\"" \
+	  $(STRIP_DLL_VERSION) $(EXPLICIT) $(CFLAGS_PERSONAL) $(CADD) \
+	  -o $@ $<
+
+typegen.o endiangen.o:%.o:%.c
+	$(CC_FOR_BUILD) -c $(CFLAGS_FOR_BUILD) -o $@ $<
+
+$(PROGS):%:%.o
+	$(LD_FOR_BUILD) -o $@ $<
+
+clean: cleanlocal
+.PHONY: cleanlocal
+cleanlocal:
+	rm -f $(PROGS)
+
diff --git a/buildtools/Makefile.manpage b/buildtools/Makefile.manpage
new file mode 100644
index 00000000..e8c17972
--- /dev/null
+++ b/buildtools/Makefile.manpage
@@ -0,0 +1,366 @@
+# -*-makefile-*-    <-- an Emacs control
+
+# Make Unix man pages from Netpbm HTML user manual
+
+MAKEMAN = makeman
+
+MANDIR = /usr/share/man/man1
+
+# These can convert to man pages cleanly
+MAN1 = \
+	411toppm.1 \
+	anytopnm.1 \
+	asciitopgm.1 \
+	atktopbm.1 \
+	bioradtopgm.1 \
+	bmptopnm.1 \
+	bmptoppm.1 \
+	brushtopbm.1 \
+	cmuwmtopbm.1 \
+	ddbugtopbm.1 \
+	escp2topbm.1 \
+	eyuvtoppm.1 \
+	fiascotopnm.1 \
+	fitstopnm.1 \
+	fstopgm.1 \
+	g3topbm.1 \
+	gemtopbm.1 \
+	gemtopnm.1 \
+	giftopnm.1 \
+	gouldtoppm.1 \
+	hdifftopam.1 \
+	hipstopgm.1 \
+	hpcdtoppm.1 \
+	icontopbm.1 \
+	ilbmtoppm.1 \
+	imgtoppm.1 \
+	infotopam.1 \
+	jbigtopnm.1 \
+	jpeg2ktopam.1 \
+	jpegtopnm.1 \
+	leaftoppm.1 \
+	lispmtopgm.1 \
+	macptopbm.1 \
+	mdatopbm.1 \
+	mgrtopbm.1 \
+	mrf.1 \
+	mrftopbm.1 \
+	mtvtoppm.1 \
+	neotoppm.1 \
+	palmtopnm.1 \
+	pamarith.1 \
+	pamchannel.1 \
+	pamcomp.1 \
+	pamcut.1 \
+	pamdeinterlace.1 \
+	pamdice.1 \
+	pamditherbw.1 \
+	pamedge.1 \
+	pamendian.1 \
+	pamfile.1 \
+	pamflip.1 \
+	pamfunc.1 \
+	pamgauss.1 \
+	pamlookup.1 \
+	pamoil.1 \
+	pamperspective.1 \
+	pampop9.1 \
+	pamscale.1 \
+	pamseq.1 \
+	pamsharpmap.1 \
+	pamsharpness.1 \
+	pamslice.1 \
+	pamstack.1 \
+	pamstereogram.1 \
+	pamstretch-gen.1 \
+	pamstretch.1 \
+	pamsummcol.1 \
+	pamsumm.1 \
+	pamtodjvurle.1 \
+	pamtohdiff.1 \
+	pamtohtmltbl.1 \
+	pamtojpeg2k.1 \
+	pamtopfm.1 \
+	pamtopnm.1 \
+	pamtotga.1 \
+	pamtouil.1 \
+	pbmclean.1 \
+	pbmlife.1 \
+	pbmmake.1 \
+	pbmmask.1 \
+	pbmpage.1 \
+	pbmpscale.1 \
+	pbmreduce.1 \
+	pbmtext.1 \
+	pbmtextps.1 \
+	pbmto10x.1 \
+	pbmto4425.1 \
+	pbmtoascii.1 \
+	pbmtoatk.1 \
+	pbmtobbnbg.1 \
+	pbmtocmuwm.1 \
+	pbmtodjvurle.1 \
+	pbmtoepsi.1 \
+	pbmtoepson.1 \
+	pbmtoescp2.1 \
+	pbmtog3.1 \
+	pbmtogem.1 \
+	pbmtogo.1 \
+	pbmtoicon.1 \
+	pbmtolj.1 \
+	pbmtoln03.1 \
+	pbmtolps.1 \
+	pbmtomacp.1 \
+	pbmtomda.1 \
+	pbmtomgr.1 \
+	pbmtomrf.1 \
+	pbmtonokia.1 \
+	pbmtopgm.1 \
+	pbmtopi3.1 \
+	pbmtopk.1 \
+	pbmtoplot.1 \
+	pbmtoppa.1 \
+	pbmtopsg3.1 \
+	pbmtoptx.1 \
+	pbmtowbmp.1 \
+	pbmtox10bm.1 \
+	pbmtoxbm.1 \
+	pbmtoybm.1 \
+	pbmtozinc.1 \
+	pbmupc.1 \
+	pc1toppm.1 \
+	pcdovtoppm.1 \
+	pcxtoppm.1 \
+	pfmtopam.1 \
+	pgmabel.1 \
+	pgmbentley.1 \
+	pgmcrater.1 \
+	pgmedge.1 \
+	pgmenhance.1 \
+	pgmhist.1 \
+	pgmkernel.1 \
+	pgmminkowski.1 \
+	pgmmorphconv.1 \
+	pgmnoise.1 \
+	pgmnorm.1 \
+	pgmoil.1 \
+	pgmramp.1 \
+	pgmslice.1 \
+	pgmtexture.1 \
+	pgmtofs.1 \
+	pgmtolispm.1 \
+	pgmtopbm.1 \
+	pgmtopgm.1 \
+	pgmtoppm.1 \
+	pi1toppm.1 \
+	pi3topbm.1 \
+	picttoppm.1 \
+	pjtoppm.1 \
+	pktopbm.1 \
+	pngtopnm.1 \
+	pnmalias.1 \
+	pnmarith.1 \
+	pnmcat.1 \
+	pnmcolormap.1 \
+	pnmcomp.1 \
+	pnmconvol.1 \
+	pnmcrop.1 \
+	pnmcut.1 \
+	pnmdepth.1 \
+	pnmenlarge.1 \
+	pnmfile.1 \
+	pnmgamma.1 \
+	pnmhisteq.1 \
+	pnmhistmap.1 \
+	pnmindex.1 \
+	pnminterp.1 \
+	pnminvert.1 \
+	pnmmargin.1 \
+	pnmmontage.1 \
+	pnmnlfilt.1 \
+	pnmnoraw.1 \
+	pnmnorm.1 \
+	pnmpad.1 \
+	pnmpaste.1 \
+	pnmpsnr.1 \
+	pnmquant.1 \
+	pnmremap.1 \
+	pnmrotate.1 \
+	pnmscalefixed.1 \
+	pnmscale.1 \
+	pnmshear.1 \
+	pnmsmooth.1 \
+	pnmsplit.1 \
+	pnmstitch.1 \
+	pnmtile.1 \
+	pnmtoddif.1 \
+	pnmtofiasco.1 \
+	pnmtofits.1 \
+	pnmtojbig.1 \
+	pnmtojpeg.1 \
+	pnmtopalm.1 \
+	pnmtopclxl.1 \
+	pnmtoplainpnm.1 \
+	pnmtopng.1 \
+	pnmtopnm.1 \
+	pnmtops.1 \
+	pnmtorast.1 \
+	pnmtorle.1 \
+	pnmtosgi.1 \
+	pnmtosir.1 \
+	pnmtotiffcmyk.1 \
+	pnmtotiff.1 \
+	pnmtoxwd.1 \
+	ppm3d.1 \
+	ppmbrighten.1 \
+	ppmchange.1 \
+	ppmcie.1 \
+	ppmcolormask.1 \
+	ppmdim.1 \
+	ppmdist.1 \
+	ppmdither.1 \
+	ppmfade.1 \
+	ppmflash.1 \
+	ppmforge.1 \
+	ppmglobe.1 \
+	ppmhist.1 \
+	ppmlabel.1 \
+	ppmmake.1 \
+	ppmmix.1 \
+	ppmnorm.1 \
+	ppmntsc.1 \
+	ppmpat.1 \
+	ppmquantall.1 \
+	ppmquant.1 \
+	ppmrainbow.1 \
+	ppmrelief.1 \
+	ppmrough.1 \
+	ppmshadow.1 \
+	ppmshift.1 \
+	ppmspread.1 \
+	ppmsvgalib.1 \
+	ppmtoacad.1 \
+	ppmtoarbtxt.1 \
+	ppmtobmp.1 \
+	ppmtoeyuv.1 \
+	ppmtogif.1 \
+	ppmtoicr.1 \
+	ppmtoilbm.1 \
+	ppmtojpeg.1 \
+	ppmtoleaf.1 \
+	ppmtolj.1 \
+	ppmtomitsu.1 \
+	ppmtompeg.1 \
+	ppmtoneo.1 \
+	ppmtopcx.1 \
+	ppmtopgm.1 \
+	ppmtopi1.1 \
+	ppmtopict.1 \
+	ppmtopj.1 \
+	ppmtopjxl.1 \
+	ppmtoppm.1 \
+	ppmtopuzz.1 \
+	ppmtorgb3.1 \
+	ppmtosixel.1 \
+	ppmtoterm.1 \
+	ppmtotga.1 \
+	ppmtouil.1 \
+	ppmtowinicon.1 \
+	ppmtoxpm.1 \
+	ppmtoyuv.1 \
+	ppmtoyuvsplit.1 \
+	ppmtv.1 \
+	ppmwheel.1 \
+	psidtopgm.1 \
+	pstopnm.1 \
+	qrttoppm.1 \
+	rasttopnm.1 \
+	rawtopgm.1 \
+	rawtoppm.1 \
+	rgb3toppm.1 \
+	rletopnm.1 \
+	sbigtopgm.1 \
+	sgitopnm.1 \
+	sirtopnm.1 \
+	sldtoppm.1 \
+	spctoppm.1 \
+	spottopgm.1 \
+	sputoppm.1 \
+	tgatoppm.1 \
+	thinkjettopbm.1 \
+	tifftopnm.1 \
+	vidtoppm.1 \
+	wbmptopbm.1 \
+	winicontoppm.1 \
+	xbmtopbm.1 \
+	ximtoppm.1 \
+	xpmtoppm.1 \
+	xvminitoppm.1 \
+	xwdtopnm.1 \
+	ybmtopbm.1 \
+	yuvsplittoppm.1 \
+	yuvtoppm.1 \
+	zeisstopnm.1 \
+
+MAN3 = \
+	libnetpbm.3 \
+	libnetpbm_image.3 \
+	libnetpbm_ug.3 \
+	libpbm.3 \
+	libpgm.3 \
+	libpm.3 \
+	libpnm.3 \
+	libppm.3 \
+	libsystem.3 \
+	libtmpfile.3 \
+
+MAN5 = \
+	extendedopacity.5 \
+	pam.5 \
+	pbm.5 \
+	pgm.5 \
+	pnm.5 \
+	ppm.5 \
+
+MANPAGES = $(MAN1) netpbm.1 $(MAN3) $(MAN5)
+HTMLMANUALS = $(MAN1:.1=.html) $(MAN3:.3=.html) $(MAN5:.5=.html)
+XML = $(HTMLMANUALS:.html=.xml) netpbm.xml
+
+# These things don't get converted to manual pages
+# They're basically link lists, not useful in the man hierarchy.
+EXCEPTIONS = directory.html libnetpbm_dir.html
+
+# Make man pages -- reports bad lines to standard error
+manpages:
+	@python $(MAKEMAN) index.html $(HTMLMANUALS) 
+	mv index.1 netpbm.1
+
+# Make XML pages, and validate them.
+xmlpages:
+	@for x in $(MANPAGES); do doclifter $$x; done
+	@for x in $(XML); do xmllint -xinclude --postvalid $$x >/dev/null; done
+
+# This will install the generated man pages
+installman: manpages
+	for f in $(MAN1); do \
+	  if [ -f $$f ]; then gzip <$$f >$(MANDIR)/man1/$$f.gz; fi; \
+	  done
+	for f in $(MAN3); do \
+	  if [ -f $$f ]; then gzip <$$f >$(MANDIR)/man3/$$f.gz; fi; \
+	  done
+	for f in $(MAN5); do \
+	  if [ -f $$f ]; then gzip <$$f >$(MANDIR)/man5/$$f.gz; fi; \
+	  done
+	# Clean up old locations on Fedora Core 2
+	rm -f $(MANDIR)/man1/extendedopacity.1.gz 
+	rm -f $(MANDIR)/man3/directory.3.gz
+	rm -f $(MANDIR)/man3/libnetpbm_dir.3.gz
+	# remove pointer man pages (that say, "The man page isn't here")
+	# which might have been installed previously
+	for f in $(MAN1); do rm -f $(MANDIR)/man1/$$f; done
+	for f in $(MAN3); do rm -f $(MANDIR)/man3/$$f; done
+	for f in $(MAN5); do rm -f $(MANDIR)/man5/$$f; done
+
+clean:
+	@rm -f *.[135] $(XML)
+
diff --git a/buildtools/README.pkg b/buildtools/README.pkg
new file mode 100644
index 00000000..b2a6b0ef
--- /dev/null
+++ b/buildtools/README.pkg
@@ -0,0 +1,144 @@
+THESE ARE THE MANUAL INSTALLATION INSTRUCTIONS FOR NETPBM
+
+Most people install using the interactive install program 'installnetpbm'
+that is in the top level directory of the Netpbm source tree.  But it 
+isn't right for everyone.  If it doesn't do what you need, you can use
+these instructions instead.
+
+
+Once you have built and packaged Netpbm, installing is pretty
+straightforward.  If you browse the package directory, you can
+probably figure it out without reading any further.
+
+
+The parts to be installed are:
+
+  Executables 
+
+    These are the basic Netpbm programs, such as 'jpegtopnm'.
+    You will find these in the 'bin' subdirectory of the package directory.
+
+    You normally want to copy all of these into a directory that is in your
+    default program search path (which is controlled by your PATH 
+    environment variable).  Typical directories for this are /bin, /usr/bin,
+    and /usr/local/bin.
+
+  Shared Library
+         
+    This is the library that all Netpbm programs need to load and link
+    to at run time.  It is in the 'lib' subdirectory of the package
+    directory.  Building a shared library is optional; if you didn't
+    do it (which means you built executables that don't require it),
+    you don't have a 'lib' subdirectory.  Shared libraries are also
+    known as dynamic libraries and DLLs.
+
+    You normally want to copy the shared library to a directory that
+    is in your system's default shared library search path.  On
+    systems that have an 'ldconfig' program, that program controls the
+    shared library search path, and you must run it after copying the
+    Netpbm shared library to its directory.  Often, simply rebooting
+    will cause it to run cleanly.
+
+    Typical directories for this are /lib, /usr/lib, and /usr/local/lib.
+
+    On Windows, the DLLs are treated like executables, so you should
+    find the 'lib' directory empty and you should find the Netpbm DLL
+    in the 'bin' directory.  You'll probably want to install the DLL
+    and the executables in the same directory, because the shared
+    library and executable search paths are the same.
+
+  Link Library
+
+    This is a static link library.  You don't need it to run Netpbm.  You
+    need it only if you want to build your own programs that use the Netpbm
+    library.  It is in the 'link' subdirectory of the package directory.
+
+    You normally want to copy the link library into a directory that is
+    in the default search path of your linker.  Typical directories for 
+    this are /usr/lib and /usr/local/lib.
+
+  Interface Headers
+
+    These are the files that declare the interface to the Netpbm 
+    programming library.  You don't need them to run Netpbm.  You need
+    them only if you want to build your own programs that use the
+    Netpbm library.  They are in the 'include' subdirectory of the 
+    package directory.
+
+    You normally want to copy the interface header files into a directory
+    that is in the default search path of your compiler.  Typical
+    directories for this are /usr/include and /usr/local/include.
+
+  Data Files
+
+    These are files that you can use for various purposes as input to
+    Netpbm programs.  People rarely have uses for them, actually.  They
+    are in the 'data' subdirectory of the package directory.
+   
+    Put these somewhere that users will be able to find them.
+    /usr/lib/netpbm and /usr/share/netpbm are typical choices.
+
+  Man Pages
+
+    Netpbm does not have the typical Unix form of documentation.  The
+    documentation is not in files that you can read with the common
+    'man' program.  Instead, it is in HTML form, and it is not in the
+    package directory at all.  You must install it separately.
+
+    But so that a user who is not familiar with Netpbm documentation
+    doesn't find himself out in the cold with no access to
+    documentation, the package directory contains traditional man
+    pages that do nothing but tell you where to get the real
+    documentation.  (Exactly where that is depends on the options with
+    which you built and packaged Netpbm).  We call these "pointer man
+    pages."  You will find these man pages in the 'man' subdirectory
+    of the package directory.
+
+    You should copy the contents of this directory wherever your 'man'
+    program looks for man pages.  Typically, this is /usr/man, which
+    has subdirectories equivalent to those in the package directory's
+    'man' subdirectory.
+
+
+    One of the Netpbm programs is Manweb, which is designed to be a
+    replacement for the classic Man program that can access both
+    traditional man pages and worldwide web documentation in the
+    Netpbm style with the familiar 'man jpegtopnm' kind of command.
+    To set up your system for this, you will have to be sure to create
+    the /usr/man/web directory, with 'netpbm.url' in it.  Also, If you
+    install Manweb as 'man', there is no point to installing the
+    pointer man pages -- they will never be used.
+    
+
+
+The instructions above suggest putting the Netpbm parts in common
+directories such as /usr/bin, mingled with other packages.  This is
+usually the easiest way to get Netpbm working.  But also consider
+putting all Netpbm parts in separate Netpbm directories, such as
+/usr/bin/netpbm/ and /usr/link/netpbm.  In fact, you can just copy the
+entire package directory in one piece to some place such as
+/usr/local/netpbm.  You'll have to take care to set up search paths
+and such to make this kind of configuration work.  The advantage of
+keeping Netpbm separate is that it makes it easy to wipe out the
+entire installation when you don't want it anymore, and to keep
+multiple versions around.
+
+
+netpbm.config
+-------------
+
+You should create a shell script named 'netpbm.config' out of the
+template file 'config_template' in the package directory, and install
+netpbm.config in your executable search path.  Programs that want to
+find out where you installed some part of Netpbm can invoke
+netpbm.config and it will tell them.  For example, a make file for a
+program that uses the Netpbm programming library might use
+netpbm.config to generate the necessary compiler and linker options to
+access that library.
+
+Using netpbm.config, it's possible to have a viable Netpbm
+installation where netpbm.config is the only file in any default
+search path.
+
+The xxx.config file concept is a relatively new but growing convention,
+seen mostly in software related to the X Window System.
diff --git a/buildtools/config_template b/buildtools/config_template
new file mode 100644
index 00000000..04a32079
--- /dev/null
+++ b/buildtools/config_template
@@ -0,0 +1,52 @@
+@ This is a template to be processed into a Bourne shell program.
+@
+#!/bin/sh
+
+# This program was generated by the Netpbm installer.  Its purpose is to
+# allow other programs to find out about how Netpbm is installed on this
+# system.  This program is supposed to be invoked via the PATH. 
+
+@ The following @xxx@ strings get replaced by Installnetpbm when it turns
+@ this template into an actual Bourne shell program.
+version='@VERSION@'
+datadir='@DATADIR@'
+linkdir='@LINKDIR@'
+includedir='@INCLUDEDIR@'
+bindir='@BINDIR@'
+
+    
+if test $# -eq 0; then
+    echo >&2 "You need to specify one of these options:"
+    echo >&2 "  --version"
+    echo >&2 "  --datadir"
+    echo >&2 "  --linkdir"
+    echo >&2 "  --includedir"
+    echo >&2 "  --bindir"
+    exit 100
+    fi
+
+case "$1" in
+    --version)
+      echo $version
+      exit 0
+      ;;
+    --datadir)
+      echo $datadir
+      exit 0
+      ;;
+    --linkdir)
+      echo $linkdir
+      exit 0
+      ;;
+    --includedir)
+      echo $includedir
+      exit 0
+      ;;
+    --bindir)
+      echo $bindir
+      exit 0
+      ;;
+    *)
+      echo >&2 "Unrecognized option to $0: $1"
+      exit 100
+    esac
diff --git a/buildtools/configure.pl b/buildtools/configure.pl
new file mode 100755
index 00000000..3a44a0da
--- /dev/null
+++ b/buildtools/configure.pl
@@ -0,0 +1,2111 @@
+#!/usr/bin/perl -w
+
+require 5.000;
+
+use strict;
+use English;
+use File::Basename;
+use Cwd 'abs_path';
+use Fcntl;
+use Config;
+#use File::Temp "tempfile";   Not available before Perl 5.6.1
+    
+
+my ($TRUE, $FALSE) = (1,0);
+
+# This program generates Makefile.config, which is included by all of the
+# Netpbm makefiles.  You run this program as the first step in building 
+# Netpbm.  (The second step is 'make').
+
+# This program is only a convenience.  It is supported to create 
+# Makefile.config any way you want.  In fact, an easy way is to copy
+# Makefile.config.in and follow the instructions in the comments therein
+# to uncomment certain lines and make other changes.
+
+# Note that if you invoke 'make' without having first run 'configure',
+# the make will call 'configure' itself when it finds
+# 'Makefile.config' missing.  That might look a little messy to the
+# user, but it isn't the normal build process.
+
+# The argument to this program is the filepath of the Makefile.config.in
+# file.  If unspecified, the default is 'Makefile.config.in' in the 
+# Netpbm source directory.
+
+# For explanations of the stuff we put in the make files, see the comments
+# in Makefile.config.in.
+
+
+# $testCc is the command we use to do test compiles.  Note that test
+# compiles are never more than heuristics, because we may be configuring
+# a build that will happen on a whole different system, which will build
+# programs to run on a third system.
+
+my $testCc;
+
+#******************************************************************************
+#
+#  SUBROUTINES
+#
+#*****************************************************************************
+
+sub autoFlushStdout() {
+    my $oldFh = select(STDOUT);
+    $OUTPUT_AUTOFLUSH = $TRUE;
+    select($oldFh);
+}
+
+
+
+sub prompt($$) {
+
+    my ($prompt, $default) = @_;
+
+    my $defaultPrompt = defined($default) ? $default : "?";
+
+    print("$prompt [$defaultPrompt] ==> ");
+
+    my $response = <STDIN>;
+
+    if (defined($response)) {
+        chomp($response);
+        if ($response eq "" && defined($default)) {
+            $response = $default;
+        }
+    } else {
+        print("\n");
+        die("End of file on Standard Input when expecting response to prompt");
+    }
+
+    return $response;
+}
+
+
+
+sub tmpdir() {
+# This is our approximation of File::Spec->tmpdir(), which became part of
+# basic Perl some time after Perl 5.005_03.
+
+    my $retval;
+    
+    if ($ENV{"TMPDIR"}) {
+        $retval = $ENV{"TMPDIR"};
+    } else {
+        if ($Config{'osvers'} eq "djgpp") {
+            $retval = "/dev/env/DJDIR/tmp";
+        } else {
+            $retval =  "/tmp";
+        }
+    }
+    return $retval;
+}
+
+
+
+sub tempFile($) {
+
+# Here's what we'd do if we could expect Perl 5.6.1 or later, instead
+# of calling this subroutine:
+#    my ($cFile, $cFileName) = tempfile("netpbmXXXX", 
+#                                       SUFFIX=>".c", 
+#                                       DIR=>File::Spec->tmpdir(),
+#                                       UNLINK=>0);
+    my ($suffix) = @_;
+    my $fileName;
+    local *file;  # For some inexplicable reason, must be local, not my
+    my $i;
+    $i = 0;
+    do {
+        $fileName = tmpdir() . "/netpbm" . $i++ . $suffix;
+    } until sysopen(*file, $fileName, O_RDWR|O_CREAT|O_EXCL);
+
+    return(*file, $fileName);
+}
+
+
+
+sub commandExists($) {
+    my ($command) = @_;
+#-----------------------------------------------------------------------------
+#  Return TRUE iff a shell command $command exists.
+#-----------------------------------------------------------------------------
+
+# Note that it's significant that the redirection on the following
+# causes it to be executed in a shell.  That makes the return code
+# from system() a lot different than if system() were to try to
+# execute the program directly.
+
+    return(system("$command 1</dev/null 1>/dev/null 2>/dev/null")/256 != 127); 
+}
+
+
+
+sub chooseTestCompiler($$) {
+
+    my ($compiler, $testCcR) = @_;
+
+    my $cc;
+
+    if (!defined($compiler)) {
+        if ($ENV{'CC'}) {
+            $cc = $ENV{'CC'};
+        } else {
+            if (commandExists('cc')) {
+                $cc = 'cc';
+            } elsif (commandExists("gcc")) {
+                $cc = 'gcc';
+            }
+        }
+    } elsif ($compiler eq 'cc') {
+        $cc = "cc";
+    } elsif ($compiler eq 'gcc') {
+        $cc = 'gcc';
+    } else {
+        die("Internal error: invalid value \"$compiler\" for \$compiler");
+    }
+    $$testCcR = $cc;
+}
+
+
+
+sub testCflags($) {
+    my ($needLocal) = @_;
+
+    my $cflags;
+
+    $cflags = "";  # initial value 
+    
+    if ($ENV{"CPPFLAGS"}) {
+        $cflags = $ENV{"CPPFLAGS"};
+    } else {
+        $cflags = "";
+    }
+    
+    if ($ENV{"CFLAGS"}) {
+        $cflags .= " " . $ENV{"CFLAGS"};
+    }
+    
+    if ($needLocal) {
+        $cflags .= " -I/usr/local/include";
+    }
+    return $cflags;
+}    
+
+
+
+sub testCompile($$$) {
+    my ($cflags, $cSourceCodeR, $successR) = @_;
+#-----------------------------------------------------------------------------
+#  Do a test compile of the program in @{$cSourceCodeR}.
+#  
+#  Return $$successR == $TRUE iff the compile succeeds (exit code 0).
+#-----------------------------------------------------------------------------
+    my ($cFile, $cFileName) = tempFile(".c");
+
+    print $cFile @{$cSourceCodeR};
+    
+    my ($oFile, $oFileName) = tempFile(".o");
+    # Note: we tried using /dev/null for the output file and got complaints
+    # from the Sun compiler that it has the wrong suffix.  2002.08.09.
+    
+    my $compileCommand = "$testCc -c -o $oFileName $cflags $cFileName";
+    print ("Doing test compile: $compileCommand\n");
+    my $rc = system($compileCommand);
+    
+    unlink($oFileName);
+    close($oFile);
+    unlink($cFileName);
+    close($cFile);
+
+    $$successR = ($rc == 0);
+}
+
+
+
+sub displayIntroduction() {
+    print("This is the Netpbm configurator.  It is an interactive dialog " .
+          "that\n");
+    print("helps you build the file 'Makefile.config' and prepare to build ");
+    print("Netpbm.\n");
+    print("\n");
+
+    print("Do not be put off by all the questions.  Configure gives you " .
+          "the \n");
+    print("opportunity to make a lot of choices, but you don't have to.  " .
+          "If \n");
+    print("you don't have reason to believe you're smarter than Configure,\n");
+    print("just take the defaults (hit ENTER) and don't sweat it.\n");
+    print("\n");
+
+    print("If you are considering having a program feed answers to the " .
+          "questions\n");
+    print("below, please read doc/INSTALL, because that's probably the " .
+          "wrong thing to do.\n");
+    print("\n");
+
+    print("Hit ENTER to begin.\n");
+    my $response = <STDIN>;
+}
+
+
+sub askAboutCygwin() {
+
+    print("Are you building in/for the Cygwin environment?\n");
+    print("\n");
+    
+    my $default;
+    if ($OSNAME eq "cygwin") {
+        $default = "y";
+    } else {
+        $default = "n";
+    }
+    
+    my $retval;
+
+    while (!defined($retval)) {
+        my $response = prompt("(y)es or (n)o", $default);
+    
+        if (uc($response) =~ /^(Y|YES)$/)  {
+            $retval = $TRUE;
+        } elsif (uc($response) =~ /^(N|NO)$/)  {
+            $retval = $FALSE;
+        } else {
+            print("'$response' isn't one of the choices.  \n" .
+                  "You must choose 'yes' or 'no' (or 'y' or 'n').\n");
+        }
+    }
+    return $retval;
+}
+
+
+
+sub askAboutDjgpp() {
+
+    print("Are you building in/for the DJGPP environment?\n");
+    print("\n");
+    
+    my $default;
+    if ($OSNAME eq "dos") {
+        $default = "y";
+    } else {
+        $default = "n";
+    }
+    
+    my $retval;
+
+    while (!defined($retval)) {
+        my $response = prompt("(y)es or (n)o", $default);
+    
+        if (uc($response) =~ /^(Y|YES)$/)  {
+            $retval = $TRUE;
+        } elsif (uc($response) =~ /^(N|NO)$/)  {
+            $retval = $FALSE;
+        } else {
+            print("'$response' isn't one of the choices.  \n" .
+                  "You must choose 'yes' or 'no' (or 'y' or 'n').\n");
+        }
+    }
+}
+
+
+
+sub computePlatformDefault($) {
+
+    my ($defaultP) = @_;
+
+    if ($OSNAME eq "linux") {
+        $$defaultP = "gnu";
+    } elsif ($OSNAME eq "cygwin") {
+        $$defaultP = "win";
+    } elsif ($OSNAME eq "dos") {
+        # DJGPP says "dos"
+        $$defaultP = "win";
+    } elsif ($OSNAME eq "aix" || $OSNAME eq "freebsd" || $OSNAME eq "darwin" ||
+             $OSNAME eq "amigaos") {
+        $$defaultP = $OSNAME;
+    } elsif ($OSNAME eq "solaris") {
+        $$defaultP = "sun";
+    } elsif ($OSNAME eq "dec_osf") {
+        $$defaultP = "tru64";
+    } else {
+        print("Unrecognized OSNAME='$OSNAME'.  No default possible\n");
+    }
+    # OK - if you know what $OSNAME is on any other platform, send me a patch!
+}
+
+
+
+sub getPlatform() {
+
+    my $platform;
+    my $default;
+
+    computePlatformDefault(\$default);
+
+    print("Which of the following best describes your platform?\n");
+ 
+    print("gnu      GNU/Linux\n");
+    print("sun      Solaris or SunOS\n");
+    print("hp       HP-UX\n");
+    print("aix      AIX\n");
+    print("win      Windows/DOS (Cygwin, DJGPP, Mingw32)\n");
+    print("tru64    Tru64\n");
+    print("irix     Irix\n");
+    print("bsd      NetBSD, BSD/OS\n");
+    print("openbsd  OpenBSD\n");
+    print("freebsd  FreeBSD\n");
+    print("darwin   Darwin or Mac OS X\n");
+    print("amigaos  Amiga\n");
+    print("unixware Unixware\n");
+    print("sco      SCO OpenServer\n");
+    print("beos     BeOS\n");
+    print("none     none of these are even close\n");
+    print("\n");
+
+    my $response = prompt("Platform", $default);
+
+    my %platform = ("gnu"      => "GNU",
+                    "sun"      => "SOLARIS",
+                    "hp"       => "HP-UX",
+                    "aix"      => "AIX",
+                    "tru64"    => "TRU64",
+                    "irix"     => "IRIX",
+                    "win"      => "WINDOWS",
+                    "beos"     => "BEOS",
+                    "bsd"      => "NETBSD",
+                    "openbsd"  => "OPENBSD",
+                    "freebsd"  => "FREEBSD",
+                    "unixware" => "UNIXWARE",
+                    "sco"      => "SCO",
+                    "darwin"   => "DARWIN",
+                    "amigaos"  => "AMIGA",
+                    "none"     => "NONE"
+                    );
+
+    $platform = $platform{$response};
+    if (!defined($platform)) {
+        print("'$response' isn't one of the choices.\n");
+        exit 8;
+    }
+
+    my $subplatform;
+
+    if ($platform eq "WINDOWS") {
+        my ($djgpp, $cygwin);
+
+        if ($OSNAME eq "dos") {
+            $djgpp = askAboutDjgpp();
+            if ($djgpp) {
+                $cygwin = $FALSE;
+            } else {
+                $cygwin = askAboutCygwin();
+            }
+        } else {
+            $cygwin = askAboutCygwin();
+            if ($cygwin) {
+                $djgpp = $FALSE;
+            } else {
+                $djgpp = askAboutDjgpp();
+            }
+        }
+
+        if ($cygwin) {
+            $subplatform = "cygwin";
+        } elsif ($djgpp) {
+            $subplatform = "djgpp";
+        } else {
+            $subplatform = "other";
+        }
+    }
+
+    return($platform, $subplatform);
+}
+
+
+
+sub getCompiler($$) {
+    my ($platform, $compilerR) = @_;
+#-----------------------------------------------------------------------------
+#  Here are some of the issues surrounding choosing a compiler:
+#
+#  - It's not just the name of the program we need -- different compilers
+#    need different options.
+#
+#  - There are basically two choices on any system:  native compiler or
+#    GNU compiler.  That's all this program recognizes, anyway.
+#
+#  - A user may well have various compilers.  Different releases, using
+#    different standard libraries, for different target machines, etc.
+#
+#  - The CC environment variable tells the default compiler.
+#
+#  - In the absence of a CC environment variable, 'cc' is the default
+#    compiler.
+#
+#  - The user must be able to specify the compiler by overriding the CC
+#    make variable (e.g. make CC=gcc2).
+#
+#  - Configure needs to do test compiles.  The test is best if it uses
+#    the same compiler that the build eventually will use, but it's 
+#    useful even if not.
+#
+# The value this subroutine returns is NOT the command name to invoke the
+# compiler.  It is simply "cc" to mean native compiler or "gcc" to mean
+# GNU compiler or undefined to express no preference.
+#-----------------------------------------------------------------------------
+    my %gccCapablePlatform = ("SOLARIS" => 1,
+                              "TRU64"   => 1,
+                              "SCO"     => 1,
+                              "AIX"     => 1,
+                              "HP"      => 1);
+
+    if ($gccCapablePlatform{$platform}) {
+        print("GNU compiler or native operating system compiler (cc)?\n");
+        print("\n");
+
+        my $default;
+
+        if ($platform eq "SOLARIS" || $platform eq "SCO" ) {
+            $default = "gcc";
+        } else {
+            $default = "cc";
+        }
+
+        my $response = prompt("gcc or cc", $default);
+
+        if ($response eq "gcc") {
+            $$compilerR = "gcc";
+        } elsif ($response eq "cc") {
+            $$compilerR = "cc";
+        } else {
+            print("'$response' isn't one of the choices.  \n" .
+                  "You must choose 'gcc' or 'cc'.\n");
+            exit 12;
+        }
+
+        if ($$compilerR eq 'gcc' && !commandExists('gcc')) {
+            print("WARNING: You selected the GNU compiler, " .
+                  "but do not appear to have a program " .
+                  "named 'gcc' in your PATH.  This may " .
+                  "cause trouble later.  You may need to " .
+                  "set the CC environment variable or CC " .
+                  "makefile variable or install 'gcc'\n");
+        }
+        print("\n");
+    }
+}
+
+
+
+sub gccLinker() {
+#-----------------------------------------------------------------------------
+#  Determine what linker Gcc on this system appears to use.
+#
+#  Return either "gnu" or "sun"
+#
+#  For now, we assume it must be either a GNU linker or Sun linker and
+#  that all Sun linkers are fungible.
+#
+#  If we can't tell, we assume it is the GNU linker.
+#-----------------------------------------------------------------------------
+    # First, we assume that the compiler calls 'collect2' as the linker
+    # front end.  The specs file might specify some other program, but
+    # it usually says 'collect2'.
+    
+    my $retval;
+
+    my $collect2 = qx{gcc --print-prog-name=collect2};
+    
+    if (defined($collect2)) {
+        chomp($collect2);
+        my $linker = qx{$collect2 -v 2>&1};
+        if (defined($linker) && $linker =~ m{GNU ld}) {
+            $retval = "gnu";
+        } else {
+            $retval = "sun";
+        }
+    } else {
+        $retval = "gnu";
+    }
+    return $retval;
+}
+
+
+
+sub getLinker($$$$) {
+
+    my ($platform, $compiler, $baseLinkerR, $viaCompilerR) = @_;
+
+    my $baseLinker;
+
+    if ($platform eq "SOLARIS") {
+        $$viaCompilerR = $TRUE;
+
+        while (!defined($$baseLinkerR)) {
+            print("GNU linker or SUN linker?\n");
+            print("\n");
+
+            my $default;
+            
+            if ($compiler eq "gcc") {
+                $default = gccLinker();
+            } else {
+                $default = "sun";
+            }
+            my $response = prompt("sun or gnu", $default);
+            
+            if ($response eq "gnu") {
+                $$baseLinkerR = "GNU";
+            } elsif ($response eq "sun") {
+                $$baseLinkerR = "SUN";
+            } else {
+                print("'$response' isn't one of the choices.  \n" .
+                      "You must choose 'sun' or 'gnu'.\n");
+            }
+            print("\n");
+        }
+    } else {
+        $$viaCompilerR = $TRUE;
+        $$baseLinkerR = "?";
+    }
+}
+
+
+
+sub libSuffix($) {
+    my ($platform) = @_;
+#-----------------------------------------------------------------------------
+#  Return the traditional suffix for the link-time library on platform
+#  type $platform.
+#
+#  Note that this information is used mainly for cosmetic purposes in this
+#  this program and the Netpbm build, because the build typically removes
+#  any suffix and uses link options such as "-ltiff" to link the library.
+#  This leaves it up to the linker to supply the actual suffix.
+#-----------------------------------------------------------------------------
+    my $suffix;
+
+    if ($platform eq "windows") {
+        $suffix = ".a";
+    } else {
+        $suffix = ".so";
+    }
+}
+
+
+
+sub getLibTypes($$$$$$$$) {
+    my ($platform, $subplatform, $default_target,
+        $netpbmlibtypeR, $netpbmlibsuffixR, $shlibprefixlistR,
+        $willBuildSharedR, $staticlib_tooR) = @_;
+
+    print("Do you want libnetpbm to be statically linked or shared?\n");
+    print("\n");
+
+    my $default = ($default_target eq "merge") ? "static" : "shared";
+
+    my ($netpbmlibtype, $netpbmlibsuffix, $shlibprefixlist, 
+        $willBuildShared, $staticlib_too);
+    
+    my $response = prompt("static or shared", $default);
+    
+    if ($response eq "shared") {
+        $willBuildShared = $TRUE;
+        if ($platform eq "WINDOWS") {
+            $netpbmlibtype = "dll";
+            $netpbmlibsuffix = "dll";
+            if ($subplatform eq "cygwin") {
+                $shlibprefixlist = "cyg lib";
+            } 
+        } elsif ($platform eq "DARWIN") {
+            $netpbmlibtype = "dylib";
+            $netpbmlibsuffix = "dylib";
+        } else {
+	    if ($platform eq "IRIX") {
+		$netpbmlibtype = "irixshared";
+	    } else {
+		$netpbmlibtype = "unixshared";
+	    }
+            if ($platform eq "AIX") {
+                $netpbmlibsuffix = "a";
+            } elsif ($platform eq "HP-UX") {
+                $netpbmlibsuffix = "sl";
+            } else {
+                $netpbmlibsuffix = "so";
+            }
+        }
+    } elsif ($response eq "static") {
+        $willBuildShared = $FALSE;
+        $netpbmlibtype = "unixstatic";
+        $netpbmlibsuffix = "a";
+        # targets, but needed for building
+        # libopt 
+    } else {
+        print("'$response' isn't one of the choices.  \n" .
+              "You must choose 'static' or 'shared'.\n");
+        exit 12;
+    }
+
+    print("\n");
+
+    # Note that we can't do both a static and shared library for AIX, because
+    # they both have the same name: libnetpbm.a.
+    
+    if (($netpbmlibtype eq "unixshared" or 
+         $netpbmlibtype eq "irixshared" or 
+         $netpbmlibtype eq "dll") and $netpbmlibsuffix ne "a") {
+        print("Do you want to build static libraries too (for linking to \n");
+        print("programs not in the Netpbm package?\n");
+        print("\n");
+        
+        my $default = "y";
+        
+        my $response = prompt("(y)es or (n)o", $default);
+        
+        if (uc($response) =~ /^(Y|YES)$/)  {
+            $staticlib_too = "y";
+        } elsif (uc($response) =~ /^(N|NO)$/)  {
+            $staticlib_too = "n";
+        } else {
+            print("'$response' isn't one of the choices.  \n" .
+              "You must choose 'yes' or 'no' (or 'y' or 'n').\n");
+            exit 12;
+        }
+    } else {
+        $staticlib_too = "n";
+    }
+    print("\n");
+
+    $$netpbmlibtypeR   = $netpbmlibtype;
+    $$netpbmlibsuffixR = $netpbmlibsuffix;
+    $$shlibprefixlistR = $shlibprefixlist;
+    $$willBuildSharedR = $willBuildShared;
+    $$staticlib_tooR   = $staticlib_too;
+}
+
+
+
+sub inttypesDefault() {
+
+    my $retval;
+
+    if (defined($testCc)) {
+
+        print("(Doing test compiles to choose a default for you -- " .
+              "ignore errors)\n");
+
+        my $cflags = testCflags($FALSE);
+
+        my $works;
+
+        # We saw a system (Irix 5.3 with native IDO, December 2005) on
+        # which sys/types.h defines uint32_t, but not int32_t and other
+        # similar types.  We saw a Mac OS X system (January 2006) on which
+        # sys/types sometimes defines uint32_t, but sometimes doesn't.
+        # So we make those last resorts.
+
+        # int_fastXXX_t are the least likely of all the types to be
+        # defined, so we look for that.
+
+        # Solaris 8, for example, has a <sys/inttypes.h> that defines
+        # int32_t and uint32_t, but nothing the defines int_fast32_t.
+
+        my @candidateList = ("<inttypes.h>", "<sys/inttypes.h>",
+                             "<types.h>", "<sys/types.h>");
+        
+        for (my $i = 0; $i < @candidateList && !$works; ++$i) {
+            my $candidate = $candidateList[$i];
+            my @cSourceCode = (
+                               "#include $candidate\n",
+                               "int_fast32_t testvar;\n"
+                               );
+            
+            testCompile($cflags, \@cSourceCode, \my $success);
+            
+            if ($success) {
+                $works = $candidate;
+            }
+        }
+        if ($works) {
+            $retval = $works;
+        } else {
+            testCompile($cflags, ["int_fast32_t testvar;"], \my $success);
+            if ($success) {
+                $retval = "NONE";
+            } else {
+                $retval = '"inttypes_netpbm.h"';
+            }
+        }
+        print("\n");
+    } else {
+        $retval = '<inttypes.h>';
+    }
+    return $retval;
+}
+
+
+
+sub getInttypes($) {
+    my ($inttypesHeaderFileR) = @_;
+
+    my $gotit;
+
+    print("What header file defines uint32_t, etc.?\n");
+    print("\n");
+
+    my $default = inttypesDefault();
+    
+    while (!$gotit) {
+        my $response = prompt("'#include' argument or NONE", $default);
+
+        if ($response eq "NONE") {
+            $$inttypesHeaderFileR = '';
+            $gotit = $TRUE;
+        } else {
+            if ($response !~ m{<.+>} &&
+                $response !~ m{".+"}) {
+                print("'$response' is not a legal argument of a C #include " .
+                      "statement.  It must be something in <> or \"\".\n");
+            } else {
+                $gotit = $TRUE;
+                $$inttypesHeaderFileR = $response;
+            }
+        }
+    }
+}
+
+
+sub getInt64($$) {
+
+    my ($inttypes_h, $haveInt64R) = @_;
+
+    if (defined($testCc)) {
+
+        print("(Doing test compiles to determine if you have int64 type -- " .
+              "ignore errors)\n");
+
+        my $cflags = testCflags($FALSE);
+
+        my $works;
+
+        my @cSourceCode = (
+                           "#include $inttypes_h\n",
+                           "int64_t testvar;\n"
+                           );
+            
+        testCompile($cflags, \@cSourceCode, \my $success);
+            
+        if ($success) {
+            print("You do.\n");
+            $$haveInt64R = 'Y';
+        } else {
+            print("You do not.  64-bit code won't be built.\n");
+            $$haveInt64R = 'N';
+        }
+        print("\n");
+    } else {
+        $$haveInt64R = "N";
+    }
+}
+
+
+
+# TODO: These should do test compiles to see if the headers are in the
+# default search path, both to create a default to offer and to issue a
+# warning after user has chosen.  Also test links to test the link library.
+
+# It looks like these should all be in the default search paths and were there
+# just to override defaults in Makefile.config.in.  Since Configure now
+# creates a default of "standard search path," I'm guessing we don't need
+# to set these anymore.
+
+sub getTiffLibrary($@) {
+
+    my ($platform, @suggestedHdrDir) = @_;
+
+    my $tifflib;
+    {
+        my $default = "libtiff" . libSuffix($platform);
+
+        print("What is your TIFF (graphics format) library?\n");
+        
+        my $response = prompt("library filename or 'none'", $default);
+        
+        if ($response ne "none") {
+            $tifflib = $response;
+        }
+        if (defined($tifflib) and $tifflib =~ m{/} and !-f($tifflib)) {
+            printf("WARNING: No regular file named '$tifflib' exists.\n");
+        }
+    }
+    my $tiffhdr_dir;
+    if (defined($tifflib)) {
+        my $default;
+
+        if (-d("/usr/include/tiff")) {
+            $default = "/usr/include/tiff";
+        } elsif (-d("/usr/include/libtiff")) {
+            $default = "/usr/include/libtiff";
+        } else {
+            $default = "default";
+        }
+        print("Where are the interface headers for it?\n");
+        
+        my $response = prompt("TIFF header directory", $default);
+        
+        if ($response ne "default") {
+            $tiffhdr_dir = $response;
+        }
+        if (defined($tiffhdr_dir) and !-d($tiffhdr_dir)) {
+            printf("WARNING: No directory named '$tiffhdr_dir' exists.\n");
+        }
+    }
+    return($tifflib, $tiffhdr_dir);
+}
+
+
+
+sub getJpegLibrary($@) {
+
+    my ($platform, @suggestedHdrDir) = @_;
+
+    my $jpeglib;
+    {
+        my $default = "libjpeg" . libSuffix($platform);
+
+        print("What is your JPEG (graphics format) library?\n");
+        
+        my $response = prompt("library filename or 'none'", $default);
+        
+        if ($response ne "none") {
+            $jpeglib = $response;
+        }
+    }
+    my $jpeghdr_dir;
+    if (defined($jpeglib)) {
+        my $default;
+
+        if (-d("/usr/include/jpeg")) {
+            $default = "/usr/include/jpeg";
+        } else {
+            $default = "default";
+        }
+        print("Where are the interface headers for it?\n");
+        
+        my $response = prompt("JPEG header directory", $default);
+        
+        if ($response ne "default") {
+            $jpeghdr_dir = $response;
+        }
+        if (defined($jpeghdr_dir) and !-d($jpeghdr_dir)) {
+            printf("WARNING: No directory named '$jpeghdr_dir' exists.\n");
+        }
+    }
+    return($jpeglib, $jpeghdr_dir);
+}
+
+
+
+sub getPngLibrary($@) {
+
+    my ($platform, @suggestedHdrDir) = @_;
+
+    my ($pnglib, $pnghdr_dir);
+
+    if (commandExists('libpng-config')) {
+        # We don't need to ask where Libpng is; there's a 'libpng-config'
+        # That tells exactly how to access it, and the make files will use
+        # that.
+    } else {
+        {
+            my $default = "libpng" . libSuffix($platform);
+
+            print("What is your PNG (graphics format) library?\n");
+            
+            my $response = prompt("library filename or 'none'", $default);
+            
+            if ($response ne "none") {
+                $pnglib = $response;
+            }
+        }
+        if (defined($pnglib)) {
+            my $default;
+
+            if (-d("/usr/include/png")) {
+                $default = "/usr/include/libpng";
+            } else {
+                $default = "default";
+            }
+            
+            print("Where are the interface headers for it?\n");
+            
+            my $response = prompt("PNG header directory", $default);
+
+            if ($response ne "default") {
+                $pnghdr_dir = $response;
+            }
+        }
+    }
+    return($pnglib, $pnghdr_dir);
+}
+
+
+
+sub getZLibrary($@) {
+
+    my ($platform, @suggestedHdrDir) = @_;
+
+    my ($zlib, $zhdr_dir);
+
+    {
+        my $default = "libz" . libSuffix($platform);
+
+        print("What is your Z (compression) library?\n");
+        
+        my $response = prompt("library filename or 'none'", $default);
+        
+        if ($response ne "none") {
+            $zlib = $response;
+        }
+    }
+    if (defined($zlib)) {
+        my $default;
+
+        if (-d("/usr/include/zlib")) {
+            $default = "/usr/include/zlib";
+        } else {
+            $default = "default";
+        }
+        
+        print("Where are the interface headers for it?\n");
+        
+        my $response = prompt("Z header directory", $default);
+        
+        if ($response ne "default") {
+            $zhdr_dir = $response;
+        }
+    }
+    return($zlib, $zhdr_dir);
+}
+
+
+
+sub getX11Library($@) {
+
+    my ($platform, @suggestedHdrDir) = @_;
+
+    my $x11lib;
+    {
+        my $default;
+
+        if (-d('/usr/link/X11')) {
+            $default = '/usr/link/X11/libX11' . libSuffix($platform);
+        } elsif (-d('/usr/lib/X11')) {
+            $default = '/usr/lib/libX11' . libSuffix($platform);
+        } else {
+            $default = "libX11" . libSuffix($platform);
+        }
+        print("What is your X11 (X client) library?\n");
+        
+        my $response = prompt("library filename or 'none'", $default);
+        
+        if ($response ne "none") {
+            $x11lib = $response;
+        }
+    }
+    my $x11hdr_dir;
+    if (defined($x11lib)) {
+        my $default;
+
+        $default = "default";
+
+        print("Where are the interface headers for it?\n");
+        
+        my $response = prompt("X11 header directory", $default);
+        
+        if ($response ne "default") {
+            $x11hdr_dir = $response;
+        }
+        if (defined($x11hdr_dir)) {
+            if (!-d($x11hdr_dir)) {
+                printf("WARNING: No directory named '$x11hdr_dir' exists.\n");
+            } elsif (!-d("$x11hdr_dir/X11")) {
+                printf("WARNING: Directory '$x11hdr_dir' does not contain " .
+                       "the requisite 'X11' subdirectory\n");
+            }
+        }
+    }
+    return($x11lib, $x11hdr_dir);
+}
+
+
+
+sub getLinuxsvgaLibrary($@) {
+
+    my ($platform, @suggestedHdrDir) = @_;
+
+    my ($svgalib, $svgalibhdr_dir);
+
+    if ($platform eq "GNU") {
+        {
+            my $default;
+
+            if (-d('/usr/link/svgalib')) {
+                $default = '/usr/link/svgalib/libvga.so';
+            } elsif (-d('/usr/lib/svgalib')) {
+                $default = '/usr/lib/svgalib/libvga.so';
+            } else {
+                $default = 'libvga.so';
+            }
+            
+            print("What is your Svgalib library?\n");
+            
+            my $response = prompt("library filename or 'none'", $default);
+            
+            if ($response ne "none") {
+                $svgalib = $response;
+            }
+        }
+    }
+    if (defined($svgalib)) {
+        my $default;
+        
+        if (-d('/usr/include/svgalib')) {
+            $default = '/usr/include/svgalib';
+        } else {
+            $default = "default";
+        }
+        print("Where are the interface headers for it?\n");
+        
+        my $response = prompt("Svgalib header directory", $default);
+        
+        if ($response ne "default") {
+            $svgalibhdr_dir = $response;
+        }
+        if (defined($svgalibhdr_dir)) {
+            if (!-d($svgalibhdr_dir)) {
+                printf("WARNING: No directory named " .
+                       "'$svgalibhdr_dir' exists.\n");
+            }
+        }
+    }
+    return($svgalib, $svgalibhdr_dir);
+}
+
+
+
+sub symlink_command() {
+
+    my $retval;
+
+    # Some Windows environments don't have symbolic links (or even a
+    # simulation via a "ln" command, but have a "cp" command which works
+    # in a pinch.  Some Windows environments have "ln", but it won't do
+    # symbolic links.
+    
+    if (commandExists("ln")) {
+        # We assume if Perl can do symbolic links, so can Ln, and vice
+        # versa.
+
+        my $symlink_exists = eval { symlink("",""); 1 };
+        
+        if ($symlink_exists) {
+            $retval = "ln -s";
+        } else {
+            $retval = "ln";
+        }
+    } elsif (commandExists("cp")) {
+        $retval = "cp";
+    } else {
+        # Well, maybe we just made a mistake.
+        $retval = "ln -s";
+    }
+    return $retval;
+}
+
+
+
+sub help() {
+
+    print("This is the Netpbm custom configuration program.  \n");
+    print("It is not GNU Configure.\n");
+    print("\n");
+    print("There is one optional argument to this program:  The " .
+          "name of the file to use as the basis for the Makefile.config " .
+          "file.  Default is 'Makefile.config.in'\n");
+    print("\n");
+    print("Otherwise, the program is interactive.\n");
+}
+
+
+
+sub gnuOptimizeOpt($) {
+    my ($gccCommandName) = @_;
+#-----------------------------------------------------------------------------
+#  Compute the -O compiler flag appropriate for a GNU system.  Ordinarily,
+#  this is just -O3.  But many popular GNU systems have a broken compiler
+#  that causes -O3 to generate incorrect code (symptom: pnmtojpeg --quality=95
+#  generates a syntax error message from shhopt).
+#-----------------------------------------------------------------------------
+# I don't know what are exactly the cases that Gcc is broken.  I know 
+# Red Hat 7.1 and 7.2 and Mandrake 8.2, running gcc 2.96.1, commonly have
+# the problem.  But it may be limited to a certain subrelease level or
+# CPU type or other environment.  People who have reported the problem have
+# reported that Gcc 3.0 doesn't have it.  Gcc 2.95.3 doesn't have it.
+
+# Note that automatic inlining happens at -O3 level, but there are some
+# subroutines in Netpbm marked for explicit inlining, and we need to disable
+# that inlining too, so we must go all the way down to -O0.
+
+    my @gccVerboseResp = `$gccCommandName --verbose 2>&1`;
+
+    my $brokenCompiler;
+    
+    if (@gccVerboseResp ==2) {
+        if ($gccVerboseResp[1] =~ m{gcc version 2.96}) {
+            $brokenCompiler = $TRUE;
+        } else {
+            $brokenCompiler = $FALSE;
+        }
+    } else {
+        $brokenCompiler = $FALSE;
+    }
+
+    my $oOpt;
+
+    if ($brokenCompiler) {
+        print("You appear to have a broken compiler which would produce \n");
+        print("incorrect code if requested to do inline optimization.\n");
+        print("Therefore, I am configuring the build to not do inline \n");
+        print("optimization.  This will make some Netpbm programs \n");
+        print("noticeably slower.  If I am wrong about your compiler, just\n");
+        print("edit Makefile.config and change -O0 to -O3 near the bottom.\n");
+        print("\n");
+        print("The problem is known to exist in the GNU Compiler \n");
+        print("release 2.96.  If you upgrade, you will not have this \n");
+        print("problem.\n");
+        print("---------------------------------------------\n");
+        print("\n");
+        $oOpt = "-O0";
+    } else {
+        $oOpt = "-O3";
+    }
+    return $oOpt;
+}
+
+
+
+sub needLocal($) {
+#-----------------------------------------------------------------------------
+#  Return wether or not /usr/local paths must be added to compiles and
+#  links.  In a properly configured system, those paths should be in
+#  the compiler and linker default search paths, e.g. the compiler
+#  should search /usr/local/include and then /usr/include without any
+#  -I options needed.  But we've seen some systems where it isn't.
+#
+#  Actually, I have doubts now as to whether these misconfigured systems
+#  really exist.  This subroutine was apparently always broken, because
+#  before 04.03.15, it had "netbsd", etc. in lower case.  So it always
+#  returned false.  I never had a complaint.  Plus, we had a bug in 
+#  Makefile.config.in wherein it wiped out the user's setting of the LDFLAGS
+#  environment variable.  This could explain /usr/local/lib not being in
+#  the path when it should have been.
+#
+#  So I've disabled this function; we'll see if we encounter any truly
+#  misconfigured systems.  04.03.15.
+#-----------------------------------------------------------------------------
+    my ($platform) = @_;
+
+    return $FALSE;  # See comments above.
+
+    my $needLocal;
+    
+    if ($platform eq "NETBSD" || $platform eq "OPENBSD" || 
+        $platform eq "FREEBSD") {
+        $needLocal = $TRUE;
+    } else {
+        $needLocal = $FALSE;
+    }
+    return $needLocal;
+}
+
+
+
+sub findProcessManagement($) {
+    my ($dontHaveProcessMgmtR) = @_;
+#-----------------------------------------------------------------------------
+#  Return $TRUE iff the system does not have <sys/wait.h> in its default
+#  search path.
+#-----------------------------------------------------------------------------
+    my $cflags = testCflags($FALSE);
+
+    my @cSourceCode = (
+                       "#include <sys/wait.h>\n",
+                       );
+    
+    testCompile($cflags, \@cSourceCode, \my $success);
+
+    if (!$success) {
+        print("Your system does not appear to have <sys/wait.h> in its " .
+              "standard compiler include path.  Therefore, we will build " .
+              "Netpbm with some function missing (e.g. the pm_system() " .
+              "function in libnetpbm and most of 'pamlookup'\n");
+        $$dontHaveProcessMgmtR = $TRUE;
+    } else {
+        $$dontHaveProcessMgmtR = $FALSE;
+    }
+}
+
+
+
+sub validateLibraries(@) {
+    my @libList = @_;
+#-----------------------------------------------------------------------------
+#  Check each library name in the list @libList for viability.
+#-----------------------------------------------------------------------------
+    foreach my $libname (@libList) {
+        if (defined($libname)) {
+            if ($libname =~ m{/} and !-f($libname)) {
+                print("WARNING: No regular file named '$libname' exists.\n");
+            } elsif (!($libname =~ m{ .* \. (so|a|sa|sl|dll|dylib) $ }x)) {
+                print("WARNING: The library name '$libname' does not have " .
+                      "a conventional suffix (.so, .a, .dll, etc.)\n");
+            }
+        }
+    }
+}
+
+
+
+sub warnJpegTiffDependency($$) {
+    my ($jpeglib, $tifflib) = @_;
+
+    if (defined($tifflib) && !defined($jpeglib)) {
+        print("WARNING: You say you have a Tiff library, " .
+              "but no Jpeg library.\n");
+        print("Sometimes the Tiff library prerequires the " .
+              "Jpeg library.  If \n");
+        print("that is the case on your system, you will " .
+              "have some links fail with\n");
+        print("missing 'jpeg...' symbols.  If so, rerun " .
+              "Configure and say you\n");
+        print("have no Tiff library either.\n");
+        print("\n");
+    }
+}
+
+
+
+sub testCompileJpeglibH($$) {
+    my ($cflags, $successR) = @_;
+#-----------------------------------------------------------------------------
+#  Do a test compile to see if we can see jpeglib.h.
+#-----------------------------------------------------------------------------
+    my @cSourceCode = (
+                       "#include <ctype.h>\n",
+                       "#include <stdio.h>\n",
+                       "#include <jpeglib.h>\n",
+                       );
+    
+    testCompile($cflags, \@cSourceCode, $successR);
+}
+
+
+
+sub testCompileJpegMarkerStruct($$) {
+    my ($cflags, $successR) = @_;
+#-----------------------------------------------------------------------------
+#  Do a test compile to see if struct jpeg_marker_struct is defined in 
+#  jpeglib.h.  Assume it is already established that the compiler works
+#  and can find jpeglib.h.
+#-----------------------------------------------------------------------------
+    my @cSourceCode = (
+                       "#include <ctype.h>\n",
+                       "#include <stdio.h>\n",
+                       "#include <jpeglib.h>\n",
+                       "struct jpeg_marker_struct test;\n",
+                       );
+
+    testCompile($cflags, \@cSourceCode, $successR);
+}
+
+
+
+sub printMissingHdrWarning($$) {
+
+    my ($name, $hdr_dir) = @_;
+
+    print("WARNING: You said the compile-time part of the $name library " .
+          "(the header\n");
+    print("files) is in ");
+
+    if (defined($hdr_dir)) {
+        print("directory '$hdr_dir', ");
+    } else {
+        print("the compiler's default search path, ");
+    }
+    print("but a test compile failed\n");
+    print("to confirm that.  If your configuration is exotic, the test " .
+          "compile might\n");
+    print("just be wrong, but otherwise the Netpbm build will fail.\n");
+    print("\n");
+    print("To fix this, either install the $name library there \n");
+    print("or re-run Configure and answer the question about the $name " .
+          "library\n");
+    print("differently.\n");
+    print("\n");
+}
+
+
+
+sub printOldJpegWarning() {
+    print("WARNING: Your JPEG library appears to be too old for Netpbm.\n");
+    print("We base this conclusion on the fact that jpeglib.h apparently\n");
+    print("does not define struct jpeg_marker_struct.\n");
+    print("If the JPEG library is not Independent Jpeg Group's Version 6b\n");
+    print("or better, the Netpbm build will fail when it attempts to build\n");
+    print("the parts that use the JPEG library.\n");
+    print("\n");
+    print("If your configuration is exotic, this test may just be wrong.\n");
+    print("Otherwise, either upgrade your JPEG library or re-run Configure\n");
+    print("and say you don't have a JPEG library.\n");
+    print("\n");
+}
+
+
+
+sub testJpegHdr($$) {
+
+    my ($needLocal, $jpeghdr_dir) = @_;
+
+    if (defined($testCc)) {
+
+        my $generalCflags = testCflags($needLocal);
+
+        my $jpegIOpt = $jpeghdr_dir ? "-I$jpeghdr_dir" : "";
+
+        testCompileJpeglibH("$generalCflags $jpegIOpt", \my $success);
+
+        if (!$success) {
+            print("\n");
+            printMissingHdrWarning("JPEG", $jpeghdr_dir);
+        } else {
+            # We can get to something named jpeglib.h, but maybe it's an old
+            # version we can't use.  Check it out.
+            testCompileJpegMarkerStruct("$generalCflags $jpegIOpt", 
+                                        \my $success);
+            if (!$success) {
+                print("\n");
+                printOldJpegWarning();
+            }
+        }
+    }
+}
+
+
+
+sub testCompileZlibH($$) {
+    my ($cflags, $successR) = @_;
+#-----------------------------------------------------------------------------
+#  Do a test compile to see if we can see zlib.h.
+#-----------------------------------------------------------------------------
+    my @cSourceCode = (
+                       "#include <zlib.h>\n",
+                       );
+    
+    testCompile($cflags, \@cSourceCode, $successR);
+}
+
+
+
+sub testCompilePngH($$) {
+    my ($cflags, $successR) = @_;
+#-----------------------------------------------------------------------------
+#  Do a test compile to see if we can see png.h, assuming we can see
+#  zlib.h, which png.h #includes.
+#-----------------------------------------------------------------------------
+    my @cSourceCode = (
+                       "#include <png.h>\n",
+                       );
+    
+    testCompile($cflags, \@cSourceCode, $successR);
+}
+
+
+
+sub testPngHdr($$$) {
+#-----------------------------------------------------------------------------
+#  Issue a warning if the compiler can't find png.h.
+#-----------------------------------------------------------------------------
+    my ($needLocal, $pnghdr_dir, $zhdr_dir) = @_;
+
+    if (defined($testCc)) {
+
+        my $generalCflags = testCflags($needLocal);
+
+        my $zlibIOpt = $zhdr_dir ? "-I$zhdr_dir" : "";
+
+        testCompileZlibH("$generalCflags $zlibIOpt", \my $success);
+        if (!$success) {
+            print("\n");
+            printMissingHdrWarning("Zlib", $zhdr_dir);
+        } else {
+            my $pngIOpt = $pnghdr_dir ? "-I$pnghdr_dir" : "";
+
+            testCompilePngH("$generalCflags $zlibIOpt $pngIOpt", 
+                            \my $success);
+
+            if (!$success) {
+                print("\n");
+                printMissingHdrWarning("PNG", $pnghdr_dir);
+            }
+        }
+    }
+}
+
+
+
+sub testLibpngConfig($) {
+    my ($needLocal) = @_;
+#-----------------------------------------------------------------------------
+#  Issue a warning if the instructions 'libpng-config' give for compiling
+#  with Libpng don't work.
+#-----------------------------------------------------------------------------
+    my $generalCflags = testCflags($needLocal);
+
+    my $pngCflags = qx{libpng-config --cflags};
+    chomp($pngCflags);
+
+    testCompilePngH("$generalCflags $pngCflags", \my $success);
+
+    if (!$success) {
+        print("\n");
+        print("Unable to compile a test PNG program using the compiler " .
+              "flags that libpng-config says to use: '$pngCflags'.\n");
+        print("This indicates that you have Libpng installed incorrectly.\n");
+        print("libpng-config gets installed as part of the Libpng package.\n");
+    } else {
+        
+
+
+    }
+}
+
+
+
+sub testConfiguration($$$$$$$) {
+
+    my ($needLocal, $jpeglib, $jpeghdr_dir,
+        $pnglib, $pnghdr_dir, $zlib, $zhdr_dir) = @_;
+
+    if (defined($jpeglib)) {
+        testJpegHdr($needLocal, $jpeghdr_dir);
+    }
+    if (defined($pnglib) && defined($zlib)) {
+        testPngHdr($needLocal, $pnghdr_dir, $zhdr_dir);
+    } elsif (commandExists('libpng-config')) {
+        testLibpngConfig($needLocal);
+    }
+
+    # TODO: We ought to validate other libraries too.  But it's not
+    # that important, because in the vast majority of cases where the
+    # user incorrectly identifies any library, it affects all the
+    # libraries and if the user can get a handle on the JPEG library
+    # problem, he will also solve problems with any other library.
+}
+
+
+
+#******************************************************************************
+#
+#  MAINLINE
+#
+#*****************************************************************************
+
+autoFlushStdout();
+
+my $configInPathArg;
+if (@ARGV > 0) {
+    if ($ARGV[0] =~ "^-") {
+        if ($ARGV[0] eq "--help") {
+            help();
+            exit(0);
+        } else {
+            die("Unrecognized option: $ARGV[0]");
+        }
+    } 
+    $configInPathArg = $ARGV[0];
+}
+
+if (stat("Makefile.config")) {
+    print("Discard existing Makefile.config?\n");
+    print("Y or N (N) ==> ");
+
+    my $answer = <STDIN>;
+    if (!defined($answer)) {
+        die("\nEnd of file on Standard Input");
+    }
+    chomp($answer);
+    if (uc($answer) ne "Y") {
+        print("Aborting at user request.\n");
+        exit(1);
+    }
+}
+
+print("\n");
+
+displayIntroduction();
+
+my ($platform, $subplatform) = getPlatform();
+
+print("\n");
+
+if ($platform eq "NONE") {
+    print("You will have to construct Makefile.config manually.  To do \n");
+    print("this, copy Makefile.config.in as Makefile.config, and then \n");
+    print("edit it.  Follow the instructions and examples in the file. \n");
+    print("Please report your results to the Netpbm maintainer so he \n");
+    print("can improve the configure program. \n");
+    exit;
+}
+
+getCompiler($platform, \my $compiler);
+getLinker($platform, $compiler, \my $baseLinker, \my $linkViaCompiler);
+
+chooseTestCompiler($compiler, \$testCc);
+
+my $netpbmlib_runtime_path;
+    # Undefined if the default from Makefile.config.in is acceptable.
+
+if ($platform eq "SOLARIS" or $platform eq "IRIX" or
+    $platform eq "DARWIN" or $platform eq "NETBSD" or
+    $platform eq "AMIGA") {
+    print("Where will the Netpbm shared library reside once installed?\n");
+    print("Enter 'default' if it will reside somewhere that the shared\n");
+    print("library loader will find it automatically.  Otherwise, \n");
+    print("this directory will get built into the Netpbm programs.\n");
+    print("\n");
+
+    my $default = "default";
+    my $response = prompt("Netpbm shared library directory", $default);
+
+    if ($response eq "default") {
+        $netpbmlib_runtime_path = "";
+    } else {
+        $netpbmlib_runtime_path = $response;
+    }
+}
+
+my $default_target;
+
+print("Do you want a regular build or a merge build?\n");
+print("If you don't know what this means, " .
+      "take the default or see doc/INSTALL\n");
+print("\n");
+
+{
+    my $default = "regular";
+    my $response = prompt("regular or merge", $default);
+    
+    if ($response eq "regular") {
+        $default_target = "nonmerge";
+    } elsif ($response eq "merge") {
+        $default_target = "merge";
+    } else {
+        print("'$response' isn't one of the choices.  \n" .
+              "You must choose 'regular' or 'merge'.\n");
+        exit 12;
+    }
+}
+
+print("\n");
+
+getLibTypes($platform, $subplatform, $default_target,
+            \my $netpbmlibtype, \my $netpbmlibsuffix, \my $shlibprefixlist,
+            \my $willBuildShared, \my $staticlib_too);
+
+
+getInttypes(\my $inttypesHeaderFile);
+
+getInt64($inttypesHeaderFile, \my $haveInt64);
+
+findProcessManagement(\my $dontHaveProcessMgmt);
+
+#******************************************************************************
+#
+#  FIND THE PREREQUISITE LIBRARIES
+#
+#*****************************************************************************
+
+print("\n\n");
+print("The following questions concern the subroutine libraries that are " .
+      "Netpbm\n");
+print("prerequisites.  Every library has a compile-time part (header " .
+      "files)\n");
+print("and a link-time part.  In the case of a shared library, these are " .
+      "both\n");
+print("part of the \"development\" component of the library, which may be " .
+      "separately\n");
+print("installable from the runtime shared library.  For each library, you " .
+      "must\n");
+print("give the filename of the link library.  If it is not in your " .
+      "linker's\n");
+print("default search path, give the absolute pathname of the file.  In " .
+      "addition,\n");
+print("you will be asked for the directory in which the library's interface " .
+      "headers\n");
+print("reside, and you can respond 'default' if they are in your compiler's " .
+      "default\n");
+print("search path.\n");
+print("\n");
+print("If you don't have the library on your system, you can enter 'none' " .
+      "as the\n");
+print("library filename and the builder will skip any part that requires " .
+      "that ");
+print("library.\n");
+print("\n");
+
+my ($jpeglib, $jpeghdr_dir) = getJpegLibrary($platform);
+print("\n");
+my ($tifflib, $tiffhdr_dir) = getTiffLibrary($platform, $jpeghdr_dir);
+print("\n");
+my ($pnglib, $pnghdr_dir)   = getPngLibrary($platform, 
+                                            $tiffhdr_dir, $jpeghdr_dir);
+print("\n");
+my ($zlib, $zhdr_dir)       = getZLibrary($platform, 
+                                          $pnghdr_dir,
+                                          $tiffhdr_dir,
+                                          $jpeghdr_dir);
+print("\n");
+my ($x11lib, $x11hdr_dir) = getX11Library($platform); 
+
+print("\n");
+my ($linuxsvgalib, $linuxsvgahdr_dir) = getLinuxsvgaLibrary($platform); 
+
+print("\n");
+
+# We should add the JBIG and URT libraries here too.  They're a little
+# more complicated because there are versions shipped with Netpbm.
+
+
+#******************************************************************************
+#
+#  CONFIGURE DOCUMENTATION
+#
+#*****************************************************************************
+
+print("What URL will you use for the main Netpbm documentation page?\n");
+print("This information does not get built into any programs or libraries.\n");
+print("It does not make anything actually install that web page.\n");
+print("It is just for including in legacy man pages.\n");
+print("\n");
+
+my $default = "http://netpbm.sourceforge.net/doc/";
+
+my $netpbm_docurl = prompt("Documentation URL", $default);
+
+print("\n");
+
+
+
+
+#******************************************************************************
+#
+#  VALIDATE THE CONFIGURATION USER HAS SELECTED
+#
+#*****************************************************************************
+
+validateLibraries($jpeglib, $tifflib, $pnglib, $zlib);
+
+warnJpegTiffDependency($jpeglib, $tifflib);
+
+testConfiguration(needLocal($platform), 
+                  $jpeglib, $jpeghdr_dir,
+                  $pnglib, $pnghdr_dir,
+                  $zlib, $zhdr_dir,
+                  );
+
+#******************************************************************************
+#
+#  FIND THE NETPBM SOURCE TREE AND INITIALIZE BUILD TREE
+#
+#*****************************************************************************
+
+my $defaultConfigInPath;
+
+if (-f("GNUmakefile")) {
+    # He's apparently running us in the source tree or an already set up
+    # build directory.
+    $defaultConfigInPath = "Makefile.config.in";
+} else {
+    my $srcdir;
+    my $done;
+
+    $done = $FALSE;
+    while (!$done) {
+        print("Where is the Netpbm source code?\n");
+
+        $srcdir = prompt("Netpbm source directory", 
+                         abs_path(dirname($0) . "/.."));
+
+        if (-f("$srcdir/GNUmakefile")) {
+            $done = $TRUE;
+        } else {
+            print("That doesn't appear to contain Netpbm source code.\n");
+            print("There is no file named 'GNUmakefile' in it.\n");
+            print("\n");
+        }    
+    }
+    unlink("GNUmakefile");
+    symlink("$srcdir/GNUmakefile", "GNUmakefile");
+    unlink("Makefile");
+    symlink("$srcdir/Makefile", "Makefile");
+
+    open(SRCDIR, ">Makefile.srcdir");
+    print(SRCDIR "SRCDIR = $srcdir\n");
+    close(SRCDIR);
+    
+    $defaultConfigInPath = "$srcdir/Makefile.config.in";
+}
+
+sub makeCompilerGcc($) {
+    my ($Makefile_configR) = @_;
+    my $compileCommand = 'gcc';
+    push(@{$Makefile_configR}, "CC = $compileCommand\n");
+    push(@{$Makefile_configR}, gnuCflags($compileCommand));
+}
+
+
+#******************************************************************************
+#
+#  BUILD Makefile.config
+#
+#*****************************************************************************
+
+sub gnuCflags($) {
+    my ($gccCommandName) = @_;
+
+    return("CFLAGS = " . gnuOptimizeOpt($gccCommandName) . " -ffast-math " .
+           " -pedantic -fno-common " . 
+           "-Wall -Wno-uninitialized -Wmissing-declarations -Wimplicit " .
+           "-Wwrite-strings -Wmissing-prototypes -Wundef\n");
+}
+
+my @Makefile_config;
+    # This is the complete Makefile.config contents.  We construct it here
+    # and ultimately write the whole thing out as Makefile.config.
+
+# First, we just read the 'Makefile.config.in' in
+
+my $configInPath;
+if (defined($configInPathArg)) {
+    $configInPath = $configInPathArg;
+} else {
+    $configInPath = $defaultConfigInPath;
+}
+open (CONFIG_IN,"<$configInPath") or
+    die("Unable to open file '$configInPath' for input.");
+
+@Makefile_config = <CONFIG_IN>;
+
+unshift(@Makefile_config, 
+        "####This file was automatically created by 'configure.'\n",
+        "####Many variables are set twice -- a generic setting, then \n",
+        "####a system-specific override at the bottom of the file.\n",
+        "####\n");
+
+close(CONFIG_IN);
+
+# Now, add the variable settings that override the default settings that are
+# done by the Makefile.config.in contents.
+
+push(@Makefile_config, "\n\n\n\n");
+push(@Makefile_config, "####Lines above were copied from Makefile.config.in " .
+     "by 'configure'.\n");
+push(@Makefile_config, "####Lines below were added by 'configure' based on " .
+     "the $platform platform.\n");
+if (defined($subplatform)) {
+    push(@Makefile_config, "####subplatform '$subplatform'\n");
+}
+
+push(@Makefile_config, "DEFAULT_TARGET = $default_target\n");
+
+push(@Makefile_config, "NETPBMLIBTYPE=$netpbmlibtype\n");
+push(@Makefile_config, "NETPBMLIBSUFFIX=$netpbmlibsuffix\n");
+if (defined($shlibprefixlist)) {
+    push(@Makefile_config, "SHLIBPREFIXLIST=$shlibprefixlist\n");
+}
+push(@Makefile_config, "STATICLIB_TOO=$staticlib_too\n");
+
+if (defined($netpbmlib_runtime_path)) {
+    push(@Makefile_config, "NETPBMLIB_RUNTIME_PATH=$netpbmlib_runtime_path\n");
+}
+
+if ($platform eq "GNU") {
+    my $compileCommand;
+    if (!commandExists("cc") && commandExists("gcc")) {
+        $compileCommand = "gcc";
+        push(@Makefile_config, "CC = $compileCommand\n");
+    } else {
+        $compileCommand = "cc";
+    }
+    push(@Makefile_config, gnuCflags($compileCommand));
+# The merged programs have a main_XXX subroutine instead of main(),
+# which would cause a warning with -Wmissing-declarations or 
+# -Wmissing-prototypes.
+    push(@Makefile_config, "CFLAGS_MERGE = " .
+         "-Wno-missing-declarations -Wno-missing-prototypes\n");
+    push(@Makefile_config, "LDRELOC = ld --reloc\n");
+    push(@Makefile_config, "LINKER_CAN_DO_EXPLICIT_LIBRARY=Y\n");
+} elsif ($platform eq "SOLARIS") {
+    push(@Makefile_config, 'LDSHLIB = -Wl,-Bdynamic,-G,-h,$(SONAME)', "\n");
+
+    push(@Makefile_config, 'NEED_RUNTIME_PATH = Y', "\n");
+    if ($compiler eq "cc") {
+        push(@Makefile_config, "CFLAGS = -O\n");
+        push(@Makefile_config, "CFLAGS_SHLIB = -Kpic\n");
+    } else {
+        makeCompilerGcc(\@Makefile_config);
+    }
+    # Before Netpbm 10.20 (January 2004), we set this to -R for 
+    # $compiler == cc and -rpath otherwise.  But now we know that the GNU
+    # compiler can also invoke a linker that needs -R, so we're more flexible.
+    if ($baseLinker eq "GNU") {
+        push(@Makefile_config, "RPATHOPTNAME = -rpath\n");
+    } else {
+        push(@Makefile_config, "RPATHOPTNAME = -R\n");
+    }
+    push(@Makefile_config, "NETWORKLD = -lsocket -lnsl\n");
+} elsif ($platform eq "HP-UX") {
+    if ($compiler eq "gcc") {
+        makeCompilerGcc(\@Makefile_config);
+        push(@Makefile_config, "CFLAGS += -fPIC\n");
+        push(@Makefile_config, "LDSHLIB = -shared -fPIC\n");
+        push(@Makefile_config, 'LDFLAGS += -Wl,+b,/usr/pubsw/lib', "\n");
+    } else {
+        # We don't know what to do here.  We used to (before 10.20) just
+        # just assume the compiler was gcc.  We know that the gcc stuff
+        # above does NOT work for HP native compiler.
+    }
+} elsif ($platform eq "AIX") {
+    push(@Makefile_config, 'LDFLAGS = -L /usr/pubsw/lib', "\n");
+    if ($compiler eq "cc") {
+        # Yes, the -L option implies the runtime as well as linktime library
+        # search path.  There's no way to specify runtime path independently.
+        push(@Makefile_config, "RPATHOPTNAME = -L\n");
+        push(@Makefile_config, "LDSHLIB = -qmkshrobj\n");
+    } else {
+        makeCompilerGcc(\@Makefile_config);
+        push(@Makefile_config, "LDSHLIB = -shared\n");
+    }
+} elsif ($platform eq "TRU64") {
+#    push(@Makefile_config, "INSTALL = installbsd\n");
+    if ($compiler eq "cc") {
+        push(@Makefile_config, 'CFLAGS = -O2 -std1', "\n");
+        push(@Makefile_config, "LDFLAGS = -call_shared -oldstyle_liblookup " .
+             "-L/usr/local/lib\n");
+        push(@Makefile_config, "LDSHLIB = -shared -expect_unresolved \"*\"\n");
+    } else {
+        # We've never tested this.  This is just here to give a user a 
+        # headstart on submitting to us the necessary information.  2002.07.04.
+        push(@Makefile_config, "CC = gcc\n");
+        push(@Makefile_config, 'CFLAGS = -O3', "\n");
+        push(@Makefile_config, "LDSHLIB = -shared\n");
+    }
+    # Between May 2000 and July 2003, we had -DLONG_32 in these options.
+    # We took it out because it generated bad code for a TRU64 user in
+    # July 2003 whose system has 64 bit long and 32 bit int.  It affects
+    # only Ppmtompeg and it isn't clear that using long instead of int is
+    # ever right anyway.
+
+    push(@Makefile_config, "OMIT_NETWORK = y\n");
+    push(@Makefile_config, "LINKER_CAN_DO_EXPLICIT_LIBRARY=Y\n");
+} elsif ($platform eq "IRIX") {
+#    push(@Makefile_config, "INSTALL = install\n");
+    push(@Makefile_config, "MANPAGE_FORMAT = cat\n");
+    push(@Makefile_config, "RANLIB = true\n");
+    push(@Makefile_config, "CFLAGS = -n32 -O3 -fullwarn\n");
+    push(@Makefile_config, "LDFLAGS = -n32\n");
+    push(@Makefile_config, "LDSHLIB = -shared -n32\n");
+} elsif ($platform eq "WINDOWS") {
+    if ($subplatform eq "cygwin") {
+        makeCompilerGcc(\@Makefile_config);
+    }
+    push(@Makefile_config, "EXE = .exe\n");
+    push(@Makefile_config, "OMIT_NETWORK = y\n");
+#    # Though it may not have the link as "ginstall", "install" in a Windows
+#    # Unix environment is usually GNU install.
+#    my $ginstall_result = `ginstall --version 2>/dev/null`;
+#    if (!$ginstall_result) {
+#        # System doesn't have 'ginstall', so use 'install' instead.
+#        push(@Makefile_config, "INSTALL = install\n");
+#    }
+    push(@Makefile_config, 'SYMLINK = ', symlink_command(), "\n");
+    push(@Makefile_config, 'DLLVER=$(NETPBM_MAJOR_RELEASE)', "\n");
+    push(@Makefile_config, "LDSHLIB = " . 
+         '-shared -Wl,--image-base=0x10000000 -Wl,--enable-auto-import', "\n");
+} elsif ($platform eq "BEOS") {
+    push(@Makefile_config, "LDSHLIB = -nostart\n");
+} elsif ($platform eq "NETBSD") {
+    push(@Makefile_config, 'CFLAGS_SHLIB = -fpic', "\n");
+} elsif ($platform eq "OPENBSD") {
+    # vedge@vedge.com.ar says on 2001.04.29 that there are a ton of 
+    # undefined symbols in the Fiasco stuff on OpenBSD.  So we'll just
+    # cut it out of the build until someone feels like fixing it.
+    push(@Makefile_config, "BUILD_FIASCO = N\n");
+} elsif ($platform eq "FREEBSD") {
+} elsif ($platform eq "AMIGA") {
+    push(@Makefile_config, "CFLAGS = -m68020-60 -ffast-math -mstackextend\n");
+} elsif ($platform eq "UNIXWARE") {
+    # Nothing to do.
+} elsif ($platform eq "SCO") {
+    # Got this from "John H. DuBois III" <spcecdt@armory.com> 2002.09.27:
+    push(@Makefile_config, "RANLIB = true\n");
+    if ($compiler eq "cc") {
+        push(@Makefile_config, "CFLAGS = -O\n");
+        push(@Makefile_config, "CFLAGS_SHLIB = -O -K pic\n");
+        push(@Makefile_config, "LD_SHLIB = -G\n");
+        push(@Makefile_config, "SHLIB_CLIB =\n");
+    } else {
+        makeCompilerGcc(\@Makefile_config);
+    }
+    push(@Makefile_config, "CFLAGS_SHLIB = -fPIC\n");
+    push(@Makefile_config, "LDSHLIB = -shared\n"); 
+    push(@Makefile_config, "NETWORKLD = -lsocket -lresolve\n");
+} elsif ($platform eq "DARWIN") {
+    push(@Makefile_config, "CC = cc -no-cpp-precomp\n");
+    push(@Makefile_config, 'CFLAGS_SHLIB = -fno-common', "\n");
+    push(@Makefile_config, "LDSHLIB = ",
+         "-dynamiclib ",
+         '-install_name $(NETPBM_RUNTIME_PATH)/libnetpbm.$(MAJ).dylib', 
+         "\n");
+#    push(@Makefile_config, "INSTALL = install\n");
+} else {
+    die ("Internal error: invalid value for \$platform: '$platform'\n");
+}
+
+if (needLocal($platform)) {
+    push(@Makefile_config, "CFLAGS += -I/usr/local/include\n");
+    push(@Makefile_config, "LDFLAGS += -L/usr/local/lib\n");
+}
+
+if ($linkViaCompiler) {
+    push(@Makefile_config, "LINKERISCOMPILER = Y\n");
+}
+
+my $flex_result = `flex --version`;
+if (!$flex_result) {
+    # System doesn't have 'flex'.  Maybe 'lex' will work.  See the
+    # make rules for Thinkjettopbm for information on our experiences
+    # with Lexes besides Flex.
+
+    my $systemRc = system('lex </dev/null &>/dev/null');
+
+    if ($systemRc >> 8 == 127) {
+        print("\n");
+        print("You do not appear to have the 'flex' or 'lex' pattern \n");
+        print("matcher generator on your system, so we will not build \n");
+        print("programs that need it (Thinkjettopbm)\n");
+        
+        print("\n");
+        print("Press ENTER to continue.\n");
+        my $key = <STDIN>;
+        print("\n");
+
+        push(@Makefile_config, "LEX=\n");
+    } else {
+        print("\n");
+        print("Using 'lex' as the pattern matcher generator, " .
+              "since we cannot\n");
+        print("find 'flex' on your system.\n");
+        print("\n");
+
+        push(@Makefile_config, "LEX = lex\n"); 
+    }
+}
+
+if (defined($tiffhdr_dir)) {
+    push(@Makefile_config, "TIFFHDR_DIR = $tiffhdr_dir\n");
+}
+if (defined($tifflib)) {
+    push(@Makefile_config, "TIFFLIB = $tifflib\n");
+}
+
+if (defined($jpeghdr_dir)) {
+    push(@Makefile_config, "JPEGHDR_DIR = $jpeghdr_dir\n");
+}
+if (defined($jpeglib)) {
+    push(@Makefile_config, "JPEGLIB = $jpeglib\n");
+}
+
+if (defined($pnghdr_dir)) {
+    push(@Makefile_config, "PNGHDR_DIR = $pnghdr_dir\n");
+}
+if (defined($pnglib)) {
+    push(@Makefile_config, "PNGLIB = $pnglib\n");
+}
+
+if (defined($zhdr_dir)) {
+    push(@Makefile_config, "ZHDR_DIR = $zhdr_dir\n");
+}
+if (defined($zlib)) {
+    push(@Makefile_config, "ZLIB = $zlib\n");
+}
+
+if (defined($x11hdr_dir)) {
+    push(@Makefile_config, "X11HDR_DIR = $x11hdr_dir\n");
+}
+if (defined($x11lib)) {
+    push(@Makefile_config, "X11LIB = $x11lib\n");
+}
+
+if (defined($linuxsvgahdr_dir)) {
+    push(@Makefile_config, "LINUXSVGAHDR_DIR = $linuxsvgahdr_dir\n");
+}
+if (defined($linuxsvgalib)) {
+    push(@Makefile_config, "LINUXSVGALIB = $linuxsvgalib\n");
+}
+
+if (defined($netpbm_docurl)) {
+    push(@Makefile_config, "NETPBM_DOCURL = $netpbm_docurl\n");
+}
+
+if ($inttypesHeaderFile ne '<inttypes.h>') {
+    push(@Makefile_config, "INTTYPES_H = $inttypesHeaderFile\n");
+}
+
+if ($haveInt64 ne 'Y') {
+    push(@Makefile_config, "HAVE_INT64 = $haveInt64\n");
+}
+
+if ($dontHaveProcessMgmt) {
+    push(@Makefile_config, "DONT_HAVE_PROCESS_MGMT = Y\n");
+}
+
+#******************************************************************************
+#
+#  WRITE OUT THE FILE
+#
+#*****************************************************************************
+
+open(MAKEFILE_CONFIG, ">Makefile.config") or
+    die("Unable to open Makefile.config for writing in the current " .
+        "directory.");
+
+print MAKEFILE_CONFIG @Makefile_config;
+
+close(MAKEFILE_CONFIG) or
+    die("Error:  Close of Makefile.config failed.\n");
+
+print("\n");
+print("We have created the file 'Makefile.config'.  Note, however, that \n");
+print("we guessed a lot at your configuration and you may want to look \n");
+print("at Makefile.config and edit it to your requirements and taste \n");
+print("before doing the make.\n");
+print("\n");
+
+
+print("Now you may proceed with 'make'\n");
+print("\n");
+
+
+exit 0;          
diff --git a/buildtools/empty_depend b/buildtools/empty_depend
new file mode 100755
index 00000000..a4ba372c
--- /dev/null
+++ b/buildtools/empty_depend
@@ -0,0 +1,19 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+# This program turns every Makefile.depend file into an empty file,
+# so that dependencies in there can't make trouble for users trying to
+# build Netpbm.  They don't need dependencies anyway, since they're 
+# building everything and not modifying anything.
+
+# Developers should do 'make dep' to create real Makefile.depend files
+# before building
+
+my $mf_list = `find . -name Makefile.depend`;
+my @mf_list = split(/\s/, $mf_list);
+foreach (@mf_list) {
+    print "Emptying $_\n";
+    open(MF, ">$_");
+    close(MF);
+}
diff --git a/buildtools/endiangen b/buildtools/endiangen
new file mode 100755
index 00000000..8783096e
--- /dev/null
+++ b/buildtools/endiangen
Binary files differdiff --git a/buildtools/endiangen.c b/buildtools/endiangen.c
new file mode 100644
index 00000000..07560c10
--- /dev/null
+++ b/buildtools/endiangen.c
@@ -0,0 +1,97 @@
+/*----------------------------------------------------------------------------
+                                 endiangen
+------------------------------------------------------------------------------
+  This is a program to create C code that declares the endianness of the
+  machine on which it is run.
+
+  It generates something like this:
+
+    #ifndef LITTLE_ENDIAN
+    #define LITTLE_ENDIAN 1234
+    #endif
+
+    #ifndef BIG_ENDIAN
+    #define BIG_ENDIAN 4321
+    #endif
+       
+    #ifndef BYTE_ORDER
+    #define BYTE_ORDER LITTLE_ENDIAN
+    #endif
+
+    #define BITS_PER_WORD 32
+    #endif
+
+    
+  Really good code usually is not sensitive to endianness.  But fast,
+  not-so-good code often is.  The best way for code to determine
+  endianness is for it to do a runtime cast of an integer to an array
+  of characters and see where the bytes land.  But if speed requires
+  even sleazier code than that, use these macros.
+
+-----------------------------------------------------------------------------*/
+#include <stdio.h>
+#include <unistd.h>
+
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+
+enum endianness {ENDIAN_LITTLE, ENDIAN_BIG};
+
+static enum endianness
+byteOrder(void) {
+    
+    enum endianness retval;
+
+    union {
+        unsigned char arrayval[2];
+        unsigned short numval;
+    } testunion;
+
+    testunion.numval = 3;
+
+    if (testunion.arrayval[0] == 3)
+        retval = ENDIAN_LITTLE;
+    else
+        retval = ENDIAN_BIG;
+
+    return retval;
+}
+
+
+
+static unsigned int
+bitsPerWord(void) {
+
+    return MAX(sizeof(long), sizeof(int)) * 8;
+}
+
+
+
+int
+main(int argc, char **argv) {
+
+    printf("/* This was generated by the program 'endiangen' */\n");
+    printf("\n");
+    printf("/* LITTLE_ENDIAN, BIG_ENDIAN, and BYTE_ORDER "
+           "may come from the C library\n");
+    printf("via ctype.h. */\n");
+    printf("#include <ctype.h>\n");
+    printf("#ifndef LITTLE_ENDIAN\n");
+    printf("#define LITTLE_ENDIAN 1234\n");
+    printf("#endif\n");
+    printf("#ifndef BIG_ENDIAN\n");
+    printf("#define BIG_ENDIAN 4321\n");
+    printf("#endif\n");
+    printf("\n");
+    printf("#ifndef BYTE_ORDER\n");
+    printf("#define BYTE_ORDER %s\n", 
+           byteOrder() == ENDIAN_LITTLE ? "LITTLE_ENDIAN" : "BIG_ENDIAN");
+    printf("#endif\n");
+    printf("\n");
+    printf("#define BITS_PER_WORD %u\n", bitsPerWord());
+
+    return 0;
+}
+
+
+
+
diff --git a/buildtools/install.sh b/buildtools/install.sh
new file mode 100755
index 00000000..cd324f3d
--- /dev/null
+++ b/buildtools/install.sh
@@ -0,0 +1,255 @@
+#! /bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd="$cpprog"
+	    shift
+	    continue;;
+
+	-d) dir_arg=true
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd="$stripprog"
+	    shift
+	    continue;;
+
+	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
+	    shift
+	    continue;;
+
+	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+                if [ -f "$1.exe" ]
+                then
+		    src=$1.exe
+                else
+                    src=$1
+                fi
+	    else
+		# this colon is to work around a 386BSD /bin/sh bug
+		:
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "install:	no input file specified"
+	exit 1
+else
+	true
+fi
+
+if [ x"$dir_arg" != x ]; then
+	dst=$src
+	src=""
+	
+	if [ -d $dst ]; then
+		instcmd=:
+	else
+		instcmd=mkdir
+	fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+	if [ -f $src -o -d $src ]
+	then
+		true
+	else
+		echo "install:  $src does not exist"
+		exit 1
+	fi
+	
+	if [ x"$dst" = x ]
+	then
+		echo "install:	no destination specified"
+		exit 1
+	else
+		true
+	fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+	if [ -d $dst ]
+	then
+		dst="$dst"/`basename $src`
+	else
+		true
+	fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='	
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+	pathcomp="${pathcomp}${1}"
+	shift
+
+	if [ ! -d "${pathcomp}" ] ;
+        then
+		$mkdirprog "${pathcomp}"
+	else
+		true
+	fi
+
+	pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+	$doit $instcmd $dst &&
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+	if [ x"$transformarg" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		dstfile=`basename $dst $transformbasename | 
+			sed $transformarg`$transformbasename
+	fi
+
+# don't allow the sed command to completely eliminate the filename
+
+	if [ x"$dstfile" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		true
+	fi
+
+# Make a temp file name in the proper directory.
+
+	dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+	$doit $instcmd $src $dsttmp &&
+
+	trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+	$doit $rmcmd -f $dstdir/$dstfile &&
+	$doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
diff --git a/buildtools/installnetpbm.pl b/buildtools/installnetpbm.pl
new file mode 100755
index 00000000..db3f6200
--- /dev/null
+++ b/buildtools/installnetpbm.pl
@@ -0,0 +1,919 @@
+#!/usr/bin/perl -w
+
+require 5.000;
+
+#Note: mkdir() must have 2 arguments as late as 5.005.
+
+use strict;
+use English;
+use Fcntl;
+use File::Basename;
+
+my ($TRUE, $FALSE) = (1,0);
+
+my $cpCommand;
+#use vars qw($cpCommand);
+
+#******************************************************************************
+#
+#  SUBROUTINES
+#
+#*****************************************************************************
+
+sub autoFlushStdout() {
+    my $oldFh = select(STDOUT); 
+    $OUTPUT_AUTOFLUSH = $TRUE;
+    select($oldFh);
+}
+
+
+
+sub prompt($$) {
+
+    my ($prompt, $default) = @_;
+
+    print("$prompt ($default) ==> ");
+
+    my $response = <STDIN>;
+
+    chomp($response);
+    if ($response eq "") {
+        $response = $default;
+    }
+
+    return $response;
+}
+
+
+
+sub getPkgdir() {
+
+    my $pkgdir;
+
+    while (!$pkgdir) {
+    
+        print("Where is the install package you created with " .
+              "'make package'?\n");
+        my $default = "/tmp/netpbm";
+        
+        my $response = prompt("package directory", $default);
+
+        if (!-f("$response/pkginfo")) {
+            print("This does not appear to be a Netpbm install package. \n");
+            print("A file named $response/pkginfo does not exist.\n");
+            print("\n");
+        } else {
+            $pkgdir = $response;
+        }
+    }
+    print("\n");
+    return $pkgdir;
+}
+
+
+
+sub makePrefixDirectory($) {
+
+    my ($prefixDir) = @_;
+
+    if ($prefixDir ne "" and !-d($prefixDir)) {
+        print("No directory named '$prefixDir' exists.  Do you want " .
+              "to create it?\n");
+
+        my $done;
+        while (!$done) {
+            my $response = prompt("Y(es) or N(o)", "Y");
+            if (uc($response) eq "Y") {
+                my $success = mkdir($prefixDir, 0777);
+                if (!$success) {
+                print("Unable to create directory '$prefixDir'.  " .
+                      "Error is $ERRNO\n");
+            }
+                $done = $TRUE;
+            } elsif (uc($response) eq "N") {
+                $done = $TRUE;
+            } 
+        }
+    }
+}
+
+
+
+
+
+sub getPrefix() {
+
+    print("Enter the default prefix for installation locations.  " .
+          "I will use \n");
+    print("this in generating defaults for the following prompts to " .
+          "save you \n");
+    print("typing.  If you plan to spread Netpbm across your system, \n" .
+          "enter '/'.\n");
+    print("\n");
+
+    my $default;
+    if ($OSNAME eq "cygwin") {
+        $default = "/usr/local";
+    } elsif ($ENV{OSTYPE} && $ENV{OSTYPE} eq "msdosdjgpp") {
+        $default = "/dev/env/DJDIR";
+    } else {
+        $default = "/usr/local/netpbm";
+    }
+
+    my $response = prompt("install prefix", $default);
+
+    my $prefix;
+
+    # Remove possible trailing /
+    if (substr($response,-1,1) eq "/") {
+        $prefix = substr($response, 0, -1);
+    } else {
+        $prefix = $response;
+    }
+    print("\n");
+
+    makePrefixDirectory($prefix);
+
+    return $prefix;
+}
+
+
+
+sub getCpCommand() {
+#-----------------------------------------------------------------------------
+# compute the command + options need to do a recursive copy, preserving
+# symbolic links and file attributes.
+#-----------------------------------------------------------------------------
+    my $cpCommand;
+
+    # We definitely need more intelligence here, but we'll need input from
+    # users to do it.  Maybe we should just bundle GNU Cp with Netpbm as an
+    # install tool.  Maybe we should write a small recursive copy program
+    # that uses more invariant tools, like buildtools/install.sh does for
+    # single files.
+
+    if (`cp --version 2>/dev/null` =~ m/GNU/) {
+        # It's GNU Cp -- we have options galore, and they're readable.
+        $cpCommand = "cp --recursive --preserve --no-dereference";
+    } else {
+        # This works on Cp from "4th Berkeley Distribution", July 1994.
+        # Mac OSX has this.
+        # -R means recursive with no dereferencing of symlinks
+        # -p means preserve attributes
+        $cpCommand = "cp -R -p";
+    }
+    return($cpCommand);
+}
+
+
+
+sub getBinDir($) {
+
+    my ($prefix) = @_;
+
+    print("Where do you want the programs installed?\n");
+    print("\n");
+
+    my $binDir;
+
+    while (!$binDir) {
+        my $default = "$prefix/bin";
+
+        my $response = prompt("program directory", $default);
+        
+        if (-d($response)) {
+            $binDir = $response;
+        } else {
+            my $succeeded = mkdir($response, 0777);
+            
+            if (!$succeeded) {
+                print("Unable to create directory '$response'.  " .
+                      "Error=$ERRNO\n");
+            } else {
+                $binDir = $response;
+            }
+        }
+    }
+    print("\n");
+
+    return $binDir;
+}
+
+
+
+sub installProgram($$$) {
+
+    my ($pkgdir, $prefix, $bindirR) = @_;
+
+    my $binDir = getBinDir($prefix);
+
+    print("Installing programs...\n");
+
+    my $rc = system("$cpCommand $pkgdir/bin/* $binDir/");
+
+    if ($rc != 0) {
+        print("Copy of programs from $pkgdir/bin to $binDir failed.\n");
+        print("cp return code is $rc\n");
+    } else {
+        print("Done.\n");
+    }
+    $$bindirR = $binDir;
+}
+
+
+
+sub getLibDir($) {
+
+    my ($prefix) = @_;
+
+    print("Where do you want the shared library installed?\n");
+    print("\n");
+
+    my $libDir;
+
+    while (!$libDir) {
+        my $default = "$prefix/lib";
+
+        my $response = prompt("shared library directory", $default);
+        
+        if (-d($response)) {
+            $libDir = $response;
+        } else {
+            my $succeeded = mkdir($response, 0777);
+            
+            if (!$succeeded) {
+                print("Unable to create directory '$response'.  " .
+                      "Error=$ERRNO\n");
+            } else {
+                $libDir = $response;
+            }
+        }
+    }
+    print("\n");
+
+    return $libDir;
+}
+
+
+
+sub 
+execLdconfig() {
+#-----------------------------------------------------------------------------
+#  Run Ldconfig.  Try with the -X option first, and if that is an invalid
+#  option (which we have seen on an openBSD system), try it without -X.
+#
+#  -X means "don't create any symlinks."  Any symlinks required should be
+#  created as part of installing the library, so we don't need that function
+#  from Ldconfig.  And we want to tread as lightly as possible on the 
+#  system -- we don't want creating symlinks that have nothing to do with
+#  Netpbm to be a hidden side effect of installing Netpbm.
+#
+#  Note that this Ldconfig works only if the user installed the Netpbm
+#  library in a standard directory that Ldconfig searches.  Note that on
+#  OpenBSD, Ldconfig is hardcoded to search only /usr/lib ever.  We could
+#  also do 'ldconfig DIR' to scan the particular directory in which we
+#  installed the Netpbm library.  But 1) the effects of this would disappear
+#  the next time the user rebuilds the cache file; and 2) on OpenBSD, this
+#  causes the cache file to be rebuilt from ONLY that directory.  On OpenBSD,
+#  you can add the -m option to cause it to ADD the contents of DIR to the
+#  existing cache file.
+#  
+#-----------------------------------------------------------------------------
+# Implementation note:  We've seen varying completion codes and varying
+# error messages from different versions of Ldconfig when it fails.
+
+    my $ldconfigSucceeded;
+
+    my $ldconfigXResp = `ldconfig -X 2>&1`;
+
+    if (!defined($ldconfigXResp)) {
+        print("Unable to run Ldconfig.\n");
+        $ldconfigSucceeded = $FALSE;
+    } elsif ($ldconfigXResp eq "") {
+        $ldconfigSucceeded = $TRUE;
+    } elsif ($ldconfigXResp =~ m{usage}i) {
+        print("Trying Ldconfig again without the -X option...\n");
+
+        my $rc = system("ldconfig");
+        
+        $ldconfigSucceeded = ($rc == 0);
+    } else {
+        print($ldconfigXResp);
+        $ldconfigSucceeded = $FALSE;
+    }
+    
+    if ($ldconfigSucceeded) {
+        print("Ldconfig completed successfully.\n");
+    } else {
+        print("Ldconfig failed.  You will have to fix this later.\n");
+    }
+}
+
+
+
+sub
+doLdconfig() {
+#-----------------------------------------------------------------------------
+#  Run Ldconfig where appropriate.
+#-----------------------------------------------------------------------------
+    if ($OSNAME eq "linux" || system("ldconfig -? 2>/dev/null") != 127) {
+        # This is a system where Ldconfig makes sense
+
+        print("In order for the Netpbm shared library to be found when " .
+              "you invoke \n");
+        print("A Netpbm program, you must either set an environment " .
+              "variable to \n");
+        print("tell where to look for it, or you must put its location " .
+              "in the shared \n");
+        print("library location cache.  Do you want to run Ldconfig now " .
+              "to put the \n");
+        print("Netpbm shared library in the cache?  This works only if " .
+              "you have\n");
+        print("installed the library in a standard location.\n");
+        print("\n");
+        
+        my $done;
+
+        $done = $FALSE;
+
+        while (!$done) {
+            my $response = prompt("Y(es) or N(o)", "Y");
+
+            if (uc($response) eq "Y") {
+                execLdconfig();
+                $done = $TRUE;
+            } elsif (uc($response) eq "N") {
+                $done = $TRUE;
+            } else {
+                print("Invalid response.  Enter 'Y' or 'N'\n");
+            }
+        }
+    }
+}
+
+
+
+sub installSharedLib($$$) {
+
+    my ($pkgdir, $prefix, $libdirR) = @_;
+
+    if (-d("$pkgdir/lib")) {
+        my $libDir = getLibDir($prefix);
+
+        print("Installing shared libraries...\n");
+
+        my $rc = system("$cpCommand $pkgdir/lib/* $libDir/");
+
+        if ($rc != 0) {
+            print("Copy of libraries from $pkgdir/lib to $libDir failed.\n");
+            print("cp return code is $rc\n");
+        } else {
+            print("done.\n");
+            print("\n");
+            doLdconfig();
+        }
+        $$libdirR = $libDir;
+    } else {
+        print("You did not build a shared library, so I will not " .
+              "install one.\n");
+    }
+    print("\n");
+}
+
+
+
+sub getLinkDir($) {
+
+    my ($prefix) = @_;
+
+    print("Where do you want the static link library installed?\n");
+    print("\n");
+
+    my $linkDir;
+
+    while (!$linkDir) {
+        my $default = "$prefix/lib";
+
+        my $response = prompt("static library directory", $default);
+        
+        if (-d($response)) {
+            $linkDir = $response;
+        } else {
+            my $succeeded = mkdir($response, 0777);
+            
+            if (!$succeeded) {
+                print("Unable to create directory '$response'.  " .
+                      "Error=$ERRNO\n");
+            } else {
+                $linkDir = $response;
+            }
+        }
+    }
+    print("\n");
+
+    return $linkDir;
+}
+
+
+
+sub installStaticLib($$$) {
+
+    my ($pkgdir, $prefix, $linkdirR) = @_;
+
+    if (-d("$pkgdir/link")) {
+        my $linkDir = getLinkDir($prefix);
+
+        print("Installing link libraries.\n");
+
+        my $rc = system("$cpCommand $pkgdir/link/* $linkDir/");
+
+        if ($rc != 0) {
+            print("Copy of files from $pkgdir/link to $linkDir failed.\n");
+            print("cp return code is $rc\n");
+        } else {
+            print("done.\n");
+        }
+        $$linkdirR = $linkDir;
+    } else {
+        print("You did not build a static library, so I will not " .
+              "install one \n");
+    }
+}
+
+
+
+sub getDataDir($) {
+
+    my ($prefix) = @_;
+
+    print("Where do you want the data files installed?\n");
+    print("\n");
+
+    my $dataDir;
+
+    while (!$dataDir) {
+        my $default = "$prefix/lib";
+
+        my $response = prompt("data file directory", $default);
+        
+        if (-d($response)) {
+            $dataDir = $response;
+        } else {
+            my $succeeded = mkdir($response, 0777);
+            
+            if (!$succeeded) {
+                print("Unable to create directory '$response'.  " .
+                      "Error=$ERRNO\n");
+            } else {
+                $dataDir = $response;
+            }
+        }
+    }
+    print("\n");
+
+    return $dataDir;
+}
+
+
+
+sub getHdrDir($) {
+
+    my ($prefix) = @_;
+
+    print("Where do you want the library interface header files installed?\n");
+    print("\n");
+
+    my $hdrDir;
+
+    while (!$hdrDir) {
+        my $default = "$prefix/include";
+
+        my $response = prompt("header directory", $default);
+        
+        if (-d($response)) {
+            $hdrDir = $response;
+        } else {
+            my $succeeded = mkdir($response, 0777);
+            
+            if (!$succeeded) {
+                print("Unable to create directory '$response'.  " .
+                      "Error=$ERRNO\n");
+            } else {
+                $hdrDir = $response;
+            }
+        }
+    }
+    print("\n");
+
+    return $hdrDir;
+}
+
+
+
+sub installDataFile($$$) {
+
+    my ($pkgdir, $prefix, $datadirR) = @_;
+
+    my $dataDir = getDataDir($prefix);
+
+    print("Installing data files...\n");
+
+    my $rc = system("$cpCommand $pkgdir/misc/* $dataDir/");
+
+    if ($rc != 0) {
+        print("copy of data files from $pkgdir/misc to $dataDir " .
+              "failed.\n");
+        print("cp exit code is $rc\n");
+    } else {
+        $$datadirR = $dataDir;
+        print("done.\n");
+    }
+}
+
+
+
+sub installHeader($$$) {
+
+    my ($pkgdir, $prefix, $includedirR) = @_;
+
+    my $hdrDir = getHdrDir($prefix);
+
+    print("Installing interface header files...\n");
+
+    my $rc = system("$cpCommand $pkgdir/include/* $hdrDir/");
+
+    if ($rc != 0) {
+        print("copy of header files from $pkgdir/include to $hdrDir " .
+              "failed.\n");
+        print("cp exit code is $rc\n");
+    } else {
+        print("done.\n");
+    }
+    $$includedirR = $hdrDir;
+}
+
+
+
+sub getManDir($) {
+
+    my ($prefix) = @_;
+
+    print("Where do you want the man pages installed?\n");
+
+    print("\n");
+
+    my $manDir;
+
+    while (!$manDir) {
+        my $default = "$prefix/man";
+
+        my $response = prompt("man page directory", $default);
+
+        if (-d($response)) {
+            $manDir = $response;
+        } else {
+            my $succeeded = mkdir($response, 0777);
+            
+            if (!$succeeded) {
+                print("Unable to create directory '$response'.  " .
+                      "Error=$ERRNO\n");
+            } else {
+                $manDir = $response;
+            }
+        }
+    }
+    print("\n");
+
+    return $manDir;
+}
+
+
+
+sub removeObsoleteManPage($) {
+
+    my ($mandir) = @_;
+
+    unlink("$mandir/man1/pgmoil");
+    unlink("$mandir/man1/pgmnorm");
+    unlink("$mandir/man1/ppmtojpeg");
+    unlink("$mandir/man1/bmptoppm");
+    unlink("$mandir/man1/ppmtonorm");
+    unlink("$mandir/man1/ppmtouil");
+    unlink("$mandir/man1/pnmnoraw");
+    unlink("$mandir/man1/gemtopbm");
+    unlink("$mandir/man1/pnminterp");
+}
+
+
+
+sub tryToCreateManwebConf($) {
+
+    my ($manweb_conf_filename) = $@;
+
+    print("You don't have a /etc/manweb.conf, which is the " .
+          "configuration\n");
+    print("file for the 'manweb' program, which is a quick way to " .
+          "get to Netpbm\n");
+    print("documentation.  Would you like to create one now?\n");
+        
+    my $done;
+    
+    while (!$done) {
+        my $response = prompt("create /etc/manweb.conf", "Y");
+        
+        if (uc($response) eq "Y") {
+            my $successful = open(MANWEB_CONF, ">/etc/manweb.conf");
+            if (!$successful) {
+                print("Unable to create file /etc/manweb.conf.  " .
+                          "error = $ERRNO\n");
+            } else {
+                print(MANWEB_CONF "#Configuration file for Manweb\n");
+                print(MANWEB_CONF "webdir=/usr/man/web\n");
+                close(MANWEB_CONF);
+                $done = $TRUE;
+            }
+        } else {
+            $done = $TRUE;
+        }
+    }
+}
+
+
+
+sub getWebdir($) {
+    my ($manweb_conf_filename) = @_;
+#-----------------------------------------------------------------------------
+#  Return the value of the Manweb "web directory," as indicated by the
+#  Manweb configuration file $manweb_conf_filename.
+#
+#  If that file doesn't exist, or doesn't have a 'webdir' value, or
+#  the 'webdir' value is a chain of directories instead of just one,
+#  we return an undefined value.
+#-----------------------------------------------------------------------------
+    my $webdir;
+
+    my $success = open(MANWEB_CONF, "<$manweb_conf_filename");
+    if (!$success) {
+        print("Unable to open file '$manweb_conf_filename' for reading.  " .
+              "error is $ERRNO\n");
+    } else {
+        while (<MANWEB_CONF>) {
+            chomp();
+            if (/^\s*#/) {
+                #It's comment - ignore
+            } elsif (/^\s*$/) {
+                #It's a blank line - ignore
+            } elsif (/\s*(\S+)\s*=\s*(\S+)/) {
+                #It looks like "keyword=value"
+                my ($keyword, $value) = ($1, $2);
+                if ($keyword eq "webdir") {
+                    # We can't handle a multi-directory path; we're looking
+                    # only for a webdir statement naming a sole directory.
+                    if ($value !~ m{:}) {
+                        $webdir = $value;
+                    }
+                }
+            }
+        }
+        close(MANWEB_CONF);
+    }              
+
+    return $webdir
+}
+
+
+
+sub userWantsManwebSymlink($$) {
+
+    my ($webdir, $netpbmWebdir) = @_;
+
+    print("Your manweb.conf file says top level documentation " .
+          "is in $webdir, \n");
+    print("but you installed netpbm.url in $netpbmWebdir.\n");
+    print("Do you want to create a symlink in $webdir now?\n");
+
+    my $wants;
+    my $done;
+    
+    while (!$done) {
+        my $response = prompt("create symlink (Y/N)", "Y");
+        
+        if (uc($response) eq "Y") {
+            $wants = $TRUE;
+            $done = $TRUE;
+        } elsif (uc($response) eq "N") {
+            $wants = $FALSE;
+            $done = $TRUE;
+        }
+    }
+    return $wants;
+}
+
+
+
+sub makeInManwebPath($) {
+
+    my ($netpbmWebdir) = @_;
+
+    # Now we need /etc/manweb.conf to point to the directory in which we
+    # just installed netpbm.url.
+
+    if (!-f("/etc/manweb.conf")) {
+        tryToCreateManwebConf("/etc/manweb.conf");
+    }
+    if (-f("/etc/manweb.conf")) {
+        my $webdir = getWebdir("/etc/manweb.conf");
+        if (defined($webdir)) {
+            if ($webdir ne $netpbmWebdir) {
+                if (userWantsManwebSymlink($webdir, $netpbmWebdir)) {
+                    my $old = "$netpbmWebdir/netpbm.url";
+                    my $new = "$webdir/netpbm.url";
+                    mkdir($webdir, 0777);
+                    my $success = symlink($old, $new);
+                    if (!$success) {
+                        print("Failed to create symbolic link from $new to " .
+                              "$old.  Error is $ERRNO\n");
+                    }
+                }
+            }
+        }
+    }
+}
+
+
+
+sub installManPage($$$) {
+
+
+# Note: This installs the pointer man pages and the netpbm.url file for Manweb.
+
+    my ($pkgdir, $prefix, $mandirR) = @_;
+
+    my $manDir = getManDir($prefix);
+
+    print("Installing man pages...\n");
+
+    my $rc = system("$cpCommand $pkgdir/man/* $manDir/");
+
+    if ($rc != 0) {
+        print("copy of man pages from $pkgdir/man to $manDir failed.\n");
+        print("cp exit code is $rc\n");
+    } else {
+        print("done.\n");
+    }
+
+    print("\n");
+
+    removeObsoleteManPage($manDir);
+
+    makeInManwebPath("$manDir/web");
+    
+    $$mandirR = $manDir;
+}
+
+
+
+sub 
+processTemplate($$$$$$$$$) {
+    my ($templateR, $version, $bindir, $libdir, $linkdir, $datadir, 
+        $includedir, $mandir, $outputR) = @_;
+
+    my @output;
+
+    foreach (@{$templateR}) {
+        if (m{^@}) {
+            # Comment -- ignore it.
+        } else {
+            if (defined($version)) {
+                s/\@VERSION\@/$version/;
+            }
+            if (defined($bindir)) {
+                s/\@BINDIR@/$bindir/;
+            }
+            if (defined($libdir)) {
+                s/\@LIBDIR@/$libdir/;
+            }
+            if (defined($linkdir)) {
+                s/\@LINKDIR@/$linkdir/;
+            }
+            if (defined($datadir)) {
+                s/\@DATADIR@/$datadir/;
+            }
+            if (defined($includedir)) {
+                s/\@INCLUDEDIR@/$includedir/;
+            }
+            if (defined($mandir)) {
+                s/\@MANDIR@/$mandir/;
+            }
+            push(@output, $_);
+        }
+    }
+    $$outputR = \@output;
+}
+
+
+
+sub
+installConfig($$$$$$$) {
+    my ($pkgdir, 
+        $bindir, $libdir, $linkdir, $datadir, $includedir, $mandir) = @_;
+
+    my $error;
+
+    my $configTemplateFilename = dirname($0) . "/config_template";
+
+    my $templateOpened = open(TEMPLATE, "<", $configTemplateFilename);
+    if (!$templateOpened) {
+        $error = "Can't open template file '$configTemplateFilename'.\n";
+    } else {
+        my @template = <TEMPLATE>;
+
+        close(TEMPLATE);
+
+        my $versionOpened = open(VERSION, "<", "$pkgdir/VERSION");
+
+        my $version;
+        if (!$versionOpened) {
+            $error = "Unable to open $pkgdir/VERSION for reading.  " .
+                "Errno=$ERRNO\n";
+        } else {
+            $version = <VERSION>;
+            chomp($version);
+            close(VERSION);
+
+            processTemplate(\@template, $version, $bindir, $libdir,
+                            $linkdir, $datadir, $includedir, $mandir,
+                            \my $fileContentsR);
+
+            # TODO: Really, this ought to go in an independent directory,
+            # because you might want to have the Netpbm executables in
+            # some place not in the PATH and use this program, via the
+            # PATH, to find them.
+            
+            my $filename = "$bindir/netpbm-config";
+            
+            my $success = open(NETPBM_CONFIG, ">", $filename);
+            if ($success) {
+                chmod(0755, $filename);
+                foreach (@{$fileContentsR}) { print NETPBM_CONFIG; }
+                close(NETPBM_CONFIG);
+            } else {
+                $error = "Unable to open the file " .
+                    "'$filename' for writing.  Errno=$ERRNO\n";
+            }
+        }
+    }
+    if ($error) {
+        print(STDERR "Failed to create the Netpbm configuration program.  " .
+              "$error\n");
+    }
+}
+
+
+
+#******************************************************************************
+#
+#  MAINLINE
+#
+#*****************************************************************************
+
+autoFlushStdout();
+
+print("Welcome to the Netpbm install dialogue.  We will now proceed \n");
+print("to interactively install Netpbm on this system.\n");
+print("\n");
+print("You must have already built Netpbm and then packaged it for \n");
+print("installation by running 'make package'.  See the INSTALL file.\n");
+print("\n");
+
+my $pkgdir = getPkgdir();
+
+my $prefix = getPrefix();
+
+$cpCommand = getCpCommand();
+
+installProgram($pkgdir, $prefix, \my $bindir);
+print("\n");
+
+installSharedLib($pkgdir, $prefix, \my $libdir);
+print("\n");
+
+installStaticLib($pkgdir, $prefix, \my $linkdir);
+print("\n");
+
+installDataFile($pkgdir, $prefix, \my $datadir);
+print("\n");
+
+installHeader($pkgdir, $prefix, \my $includedir);
+print("\n");
+
+installManPage($pkgdir, $prefix, \my $mandir);
+print("\n");
+
+installConfig($pkgdir, 
+              $bindir, $libdir, $linkdir, $datadir, $includedir, $mandir);
+
+print("Installation is complete (except where previous error messages have\n");
+print("indicated otherwise).\n");
+
+exit(0);
diff --git a/buildtools/installosf b/buildtools/installosf
new file mode 100755
index 00000000..a4e5c262
--- /dev/null
+++ b/buildtools/installosf
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+# This program takes parameters as a Netpbm make file might pass to
+# its $(INSTALL) program and invokes OSF1 Install with the proper
+# parameters to effect what the make file wants.  If your system has
+# OSF1 Install on it, you can just set the INSTALL variable in
+# Makefile.config to "installosf" and 'make install' will work for
+# you.
+
+# Of course, you could also just install Ginstall and forget about this
+# program.
+
+PERMISSIONS=444
+while [ $# -gt 0 ]; do
+    if [ "$1" = "-c" ]; then x=x;
+    elif [ "$1" = "-s" ]; then x=x;
+    elif [ "$1" = "-m" ]; then 
+        shift
+        PERMISSIONS=$1
+    elif [ ${SOURCE_FILE}x == x ]; then
+        SOURCE_FILE=$1
+    else
+        TARGET_DIR=$1
+    fi
+    shift;
+done
+
+install -f $TARGET_DIR -m $PERMISSIONS $SOURCE_FILE
+
+
+
diff --git a/buildtools/libopt b/buildtools/libopt
new file mode 100755
index 00000000..6d84ce67
--- /dev/null
+++ b/buildtools/libopt
Binary files differdiff --git a/buildtools/libopt.c b/buildtools/libopt.c
new file mode 100644
index 00000000..132f05f2
--- /dev/null
+++ b/buildtools/libopt.c
@@ -0,0 +1,541 @@
+/*----------------------------------------------------------------------------
+                                 libopt
+------------------------------------------------------------------------------
+  This is a program to convert link library filepaths to linker options
+  that select them.  E.g. ../lib/libnetpbm.so becomes -L../lib -lnetpbm   .
+
+  Each argument is a library filepath.  The option string to identify
+  all of those library filepaths goes to Standard Output.
+
+  If there is no slash in the library filepath, we assume it is just a
+  filename to be searched for in the linker's default search path, and
+  generate a -l option, but no -L.
+
+  If an argument doesn't make sense as a library filespec, it is
+  copied verbatim, blank delimited, to the output string.
+
+  The "lib" part of the library name, which we call the prefix, may be
+  other than "lib".  The list of recognized values is compiled in as
+  the macro SHLIBPREFIXLIST (see below).
+  
+  There is no newline or null character or anything after the output.
+
+  If you specify the option "-runtime", the output includes a -R
+  option in addition, for every library after "-runtime" in the
+  arguments.  -R tells the buildtime linker to include the specified
+  library's directory in the search path that the runtime linker uses
+  to find dynamically linked libraries.
+
+  But if you compile this program with the EXPLICIT macro defined, and
+  a library filepath contains a slash, then it skips all that -L/-l
+  nonsense and just outputs the input library filepath verbatim (plus
+  any -R option).
+------------------------------------------------------------------------------
+  Why would you want to use this?
+
+  On some systems, the -L/-l output of this program has exactly the
+  same effect as the filepath input when used in the arguments to a
+  link command.  A GNU/Linux system, for example.  On others (Solaris,
+  for example), if you include /tmp/lib/libnetpbm.so in the link as a
+  link object, the executable gets built in such a way that the system
+  accesses the shared library /tmp/lib/libnetpbm.so at run time.  On the
+  other hand, if you instead put the options -L/tmp/lib -lnetpbm on the
+  link command, the executable gets built so that the system accesses
+  libnetpbm.so in its actual installed directory at runtime (that
+  location might be determined by a --rpath linker option or a
+  LD_LIBRARY_PATH environment variable at run time).
+
+  In a make file, it is nice to use the same variable as the
+  dependency of a rule that builds an executable and as the thing that
+  the rule's command uses to identify its input.  Here is an example
+  of using libopt for that:
+
+     NETPBMLIB=../lib/libnetpbm.so
+     ...
+     pbmmake: pbmmake.o $(PBMLIB)
+             ld -o pbmmake pbmmake.o `libopt $(PBMLIB)` --rpath=/lib/netpbm
+
+  Caveat: "-L../lib -lnetpbm" is NOT exactly the same as
+  "../pbm/libnetpbm.so" on any system.  All of the -l libraries are
+  searched for in all of the -L directories.  So you just might get a
+  different library with the -L/-l version than if you specify the
+  library file explicitly.
+
+  That's why you should compile with -DEXPLICIT if your linker can
+  handle explicit file names.
+
+-----------------------------------------------------------------------------*/
+#define _BSD_SOURCE 1      /* Make sure strdup() is in stdio.h */
+#define _XOPEN_SOURCE 500  /* Make sure strdup() is in string.h */
+
+#define MAX_PREFIXES 10
+
+/* Here's how to use SHLIBPREFIXLIST:  Use a -D compile option to pass in
+   a value appropriate for the platform on which you are linking libraries.
+
+   It's a blank-delimited list of prefixes that library names might
+   have.  "lib" is traditionally the only prefix, as in libc or
+   libnetpbm.  However, on Windows there is a convention of using
+   different prefixes to distinguish different co-existent versions of
+   the same library (kind of like a major number in some unices). 
+   E.g. the value "cyg lib" is appropriate for a Cygwin system.
+*/
+#ifndef SHLIBPREFIXLIST
+#  define SHLIBPREFIXLIST "lib"
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+typedef unsigned char bool;
+#ifndef TRUE
+#define TRUE (1)
+#endif
+#ifndef FALSE
+#define FALSE (0)
+#endif
+
+#ifdef DLLVERSTR
+static const char * dllverstr = DLLVERSTR;
+#else
+static const char * dllverstr = "";
+#endif
+
+bool const explicit = 
+#ifdef EXPLICIT
+TRUE
+#else
+FALSE
+#endif
+;
+
+static void
+strfree(const char * const arg) {
+    free((void*) arg);
+}
+
+
+static void
+parse_prefixlist(const char * const prefixlist, 
+                 char * parsed_prefixes[MAX_PREFIXES+1],
+                 bool * const errorP) {
+/*----------------------------------------------------------------------------
+   Given a space-separated list of tokens (suffixes), return an
+   argv-style array of pointers, each to a newly malloc'ed storage
+   area the prefix as a null-terminated string.  Return a null string
+   for the unused entries at the end of the array
+
+   We never return more than MAX_PREFIXES prefixes from the input, so
+   there is guaranteed always to be one null string at the end of the
+   array.
+
+   In case of error, return *errorP == TRUE and don't allocate any
+   storage.  Otherwise, return *errorP = FALSE.
+-----------------------------------------------------------------------------*/
+    char * prlist;
+
+    prlist = strdup(prefixlist);
+    if (prlist == NULL)
+        *errorP = TRUE;
+    else {
+        if (strlen(prlist) <= 0) 
+            *errorP = TRUE;
+        else {
+            /* NOTE: Mac OS X, at least, does not have strtok_r().
+               2001.09.24
+            */
+            char * token;
+            int num_tokens;
+            int i;
+            
+            for (i=0; i < MAX_PREFIXES + 1; i++) {
+                parsed_prefixes[i] = NULL;
+            }
+            num_tokens = 0;
+            token = strtok(prlist, " ");
+            *errorP = FALSE;  /* initial value */
+            while (token != NULL && num_tokens < MAX_PREFIXES && !*errorP) {
+                parsed_prefixes[num_tokens] = strdup (token);
+                if (parsed_prefixes[num_tokens] == NULL) 
+                    *errorP = TRUE;
+                num_tokens++;
+                token = strtok(NULL, " ");
+            }
+            for (i = num_tokens; i < MAX_PREFIXES + 1 && !*errorP;  i++) {
+                parsed_prefixes[i] = strdup("");
+                if (parsed_prefixes[i] == NULL) 
+                    *errorP = TRUE;
+            }
+        }
+        if (*errorP) {
+            /* Deallocate any array entries we successfully did */
+            int i;
+            for (i = 0; i < MAX_PREFIXES + 1; i++)
+                if (parsed_prefixes[i])
+                    free(parsed_prefixes[i]);
+        }
+        free(prlist);
+    }
+}
+
+
+
+static void
+parse_prefix(const char * const filename, 
+             bool * const prefix_good_p, unsigned int * const prefix_length_p,
+             bool * const error_p) {
+/*----------------------------------------------------------------------------
+   Find the library name prefix (e.g. "lib") in the library filename
+   'filename'.
+   
+   Return the length of the prefix, in characters, as *prefix_length_p.
+   (The prefix always starts at the beginning of the filename).
+
+   Iff we don't find a valid library name prefix, return *prefix_good_p
+   == FALSE.  
+
+   The list of valid prefixes is compiled in as the blank-delimited
+   string which is the value of the SHLIBPREFIXLIST macro.
+-----------------------------------------------------------------------------*/
+    char * shlibprefixlist[MAX_PREFIXES+1];
+        /* An argv-style array of prefix strings in the first entries, 
+           null strings in the later entries.  At most MAX_PREFIXES prefixes,
+           so at least one null string.
+        */
+    char * prefix;
+        /* The prefix that the filename actually
+           uses.  e.g. if shlibprefixlist = { "lib", "cyg", "", ... } and the
+           filename is "path/to/cyg<something>.<extension>", then 
+           prefix = "cyg".  String is in the same storage as pointed to by
+           shlibprefixlist (shlibprefixlist[1] in this example).
+        */
+    bool prefix_good;
+        /* The first part of the filename matched one of the prefixes
+           in shlibprefixlist[].
+        */
+    int prefix_length;
+    int i;
+
+    parse_prefixlist(SHLIBPREFIXLIST , shlibprefixlist, error_p);
+    if (!*error_p) {
+        if (strcmp(shlibprefixlist[0], "") == 0) {
+            fprintf(stderr, "libopt was compiled with an invalid value "
+                    "of the SHLIBPREFIX macro.  It seems to have no "
+                    "tokens.  SHLIBPREFIX = '%s'", 
+                    SHLIBPREFIXLIST);
+            exit(100);
+        }
+
+        i = 0;  /* start with the first entry in shlibprefixlist[] */
+        prefix_length = 0;  /* initial value */
+        prefix = shlibprefixlist[i];
+        prefix_good = FALSE;  /* initial value */
+        while ( (*prefix != '\0' ) && !prefix_good ) {
+            /* stop condition: shlibprefixlist has MAX_PREFIXES+1 entries.
+             * we only ever put tokens in the 0..MAX_PREFIXES-1 positions.
+             * Then, we fill DOWN from the MAX_PREFIXES position with '\0'
+             * so we insure that the shlibprefixlist array contains at 
+             * least one final '\0' string, but probably many '\0' 
+             * strings (depending on how many tokens there were).               
+             */
+            prefix_length = strlen(prefix);
+            if (strncmp(filename, prefix, prefix_length) == 0) {
+                prefix_good = TRUE;
+                /* at this point, prefix is pointing to the correct
+                 * entry, and prefix_length has the correct value.
+                 * When we bail out of the while loop because of the
+                 * !prefix_good clause, we can then use these 
+                 * vars (prefix, prefix_length) 
+                 */
+            } else {
+                prefix = shlibprefixlist[++i];
+            }
+        }
+        *prefix_length_p = prefix_length;
+        *prefix_good_p = prefix_good;
+        { 
+            int i;
+            for (i=0; i < MAX_PREFIXES + 1; i++) 
+                free (shlibprefixlist[i]);
+        }
+    }
+}
+
+
+
+static void
+parse_filename(const char *  const filename,
+               const char ** const libname_p,
+               bool *        const valid_library_p,
+               bool *        const static_p,
+               bool *        const error_p) {
+/*----------------------------------------------------------------------------
+   Extract the library name root component of the filename 'filename'.  This
+   is just a filename, not a whole pathname.
+
+   Return it in newly malloc'ed storage pointed to by '*libname_p'.
+   
+   E.g. for "libxyz.so", return "xyz".
+
+   return *valid_library_p == TRUE iff 'filename' validly names a library
+   that can be expressed in a -l linker option.
+
+   return *static_p == TRUE iff 'filename' indicates a static library.
+   (but undefined if *valid_library_p != TRUE).
+
+   return *error_p == TRUE iff some error such as out of memory prevents
+   parsing.
+
+   Do not allocate any memory if *error_p == TRUE or *valid_library_p == FALSE.
+-----------------------------------------------------------------------------*/
+    char *lastdot;  
+    /* Pointer to last period in 'filename'.  Null if none */
+    
+    /* We accept any period-delimited suffix as a library type suffix.
+       It's probably .so or .a, but is could be .kalamazoo for all we
+       care. (HOWEVER, the double-suffixed import lib used on 
+       cygwin (.dll.a) is NOT understood). 
+    */
+    char *p;
+
+    lastdot = strrchr(filename, '.');
+    if (lastdot == NULL) {
+        /* This filename doesn't have any suffix, so we don't understand
+           it as a library filename.
+        */
+        *valid_library_p = FALSE;
+        *error_p = FALSE;
+    } else {
+        unsigned int prefix_length;
+        bool prefix_good;
+
+        if (strcmp(lastdot, "a") == 0)
+            *static_p = TRUE;
+        else
+            *static_p = FALSE;
+
+        parse_prefix(filename, &prefix_good, &prefix_length, error_p);
+        if (!*error_p) {
+            if (!prefix_good) {
+                *valid_library_p = FALSE;
+            } else {
+                /* Extract everything between <prefix> and "." as 
+                   the library name root. 
+                */
+                char * libname;
+
+                libname = strdup(filename + prefix_length);
+                if (libname == NULL)
+                    *error_p = TRUE;
+                else {
+                    libname[lastdot - filename - prefix_length] = '\0';
+                    if (strlen(dllverstr) > 0) {
+                        p = strstr(libname, dllverstr);
+                        if (p) {
+                            if (libname + strlen(libname) 
+                                - strlen(dllverstr) == p) {
+                                *p = '\0';
+                            }
+                        }
+                    }
+                    if (strlen(libname) == 0) {
+                        *valid_library_p = FALSE;
+                        strfree(libname);
+                    } else
+                        *valid_library_p = TRUE;
+                }
+                *libname_p = libname;
+            }
+        }
+    }
+}   
+
+static void
+parse_filepath(const char *  const filepath,
+               const char ** const directory_p, 
+               const char ** const filename_p,
+               bool *        const error_p) {
+/*----------------------------------------------------------------------------
+   Extract the directory and filename components of the filepath 
+   'filepath' and return them in newly malloc'ed storage pointed to by
+   '*directory_p' and '*filename_p'.
+
+   If there is no directory component, return a null string for it.
+-----------------------------------------------------------------------------*/
+    char *directory;
+    char *lastslash; /* Pointer to last slash in 'filepath', or null if none */
+
+    lastslash = strrchr(filepath, '/');
+
+    if (lastslash == NULL) {
+        /* There's no directory component; the filename starts at the
+           beginning of the filepath 
+        */
+        *filename_p = strdup(filepath);
+        if (*filename_p == NULL)
+            *error_p = TRUE;
+        else {
+            directory = strdup("");
+            if (directory == NULL) {
+                *error_p = TRUE;
+                strfree(*filename_p);
+            } else
+                *error_p = FALSE;
+        }
+    } else {
+        /* Split the string at the slash we just found, into filename and 
+           directory 
+           */
+        *filename_p = strdup(lastslash+1);
+        if (*filename_p == NULL)
+            *error_p = TRUE;
+        else {
+            directory = strdup(filepath);
+            if (directory == NULL) {
+                *error_p = TRUE;
+                strfree(*filename_p);
+            } else {
+                *error_p = FALSE;
+                directory[lastslash - filepath] = '\0';
+            }
+        }
+    }
+    *directory_p = directory;
+}
+
+
+
+static void
+doOptions(const char *  const filepath, 
+          const char *  const directory,
+          const char *  const libname,
+          bool          const runtime,
+          bool          const explicit,
+          bool          const staticlib,
+          const char ** const optionsP) {
+
+    char * options;
+    char * linkopt;
+
+    if (strlen(directory) == 0) {
+        linkopt = malloc(strlen(libname) + 10);
+        sprintf(linkopt, "-l%s", libname);
+    } else {
+        if (explicit)
+            linkopt = strdup(filepath);
+        else {
+            linkopt = malloc(strlen(directory) + strlen(libname) + 10);
+            sprintf(linkopt, "-L%s -l%s", directory, libname);
+        }
+    }
+    if (runtime && !staticlib && strlen(directory) > 0) {
+        options = malloc(strlen(linkopt) + strlen(directory) + 10);
+        sprintf(options, "%s -R%s", linkopt, directory); 
+    } else
+        options = strdup(linkopt);
+    
+    strfree(linkopt);
+    
+    *optionsP = options;
+}
+
+
+
+static void
+processOneLibrary(const char *  const filepath, 
+                  bool          const runtime, 
+                  bool          const explicit,
+                  const char ** const optionsP,
+                  bool *        const errorP) {
+/*----------------------------------------------------------------------------
+   Process the library with filepath 'filepath'.  Return the resulting
+   linker option string as a newly malloced null-terminated string at
+   *optionsP.
+-----------------------------------------------------------------------------*/
+    const char *directory;
+        /* Directory component of 'filepath' */
+    const char *filename;
+        /* Filename component of 'filepath' */
+
+    parse_filepath(filepath, &directory, &filename, errorP);
+    if (!*errorP) {
+        const char *libname;
+            /* Library name component of 'filename'.  e.g. xyz in
+               libxyz.so 
+            */
+        bool valid_library;  
+            /* Our argument is a valid library filepath that can be
+               converted to -l/-L notation.  
+            */
+        bool staticlib;
+            /* Our argument appears to name a static library. */
+
+        parse_filename(filename, 
+                       &libname, &valid_library, &staticlib, errorP);
+        
+        if (!*errorP) {
+            if (valid_library) {
+                doOptions(filepath, directory, libname, 
+                          runtime, explicit, staticlib, optionsP);
+
+                strfree(libname);
+            } else
+                *optionsP = strdup(filepath);
+        }
+        strfree(directory); 
+        strfree(filename);
+    }
+}
+
+
+
+int
+main(int argc, char **argv) {
+
+    bool error;
+    bool runtime;  /* -runtime option has been seen */
+    bool quiet;    /* -quiet option has been seen */
+    int retval;
+    unsigned int arg;  /* Index into argv[] of argument we're processing */
+    char outputLine[1024];
+
+    strcpy(outputLine, "");  /* initial value */
+    runtime = FALSE;  /* initial value */
+    quiet = FALSE;   /* initial value */
+    error = FALSE;  /* no error yet */
+    for (arg = 1; arg < argc && !error; arg++) {
+        if (strcmp(argv[arg], "-runtime") == 0)
+            runtime = TRUE;
+        else if (strcmp(argv[arg], "-quiet") == 0)
+            quiet = TRUE;
+        else {
+            if (strlen(argv[arg]) > 200)
+                error = TRUE;
+            else {
+                const char * options;
+                processOneLibrary(argv[arg], runtime, explicit, 
+                                  &options, &error);
+                if (!error) {
+                    if (strlen(outputLine) + strlen(options) + 1 + 1 > 
+                        sizeof(outputLine))
+                        error = TRUE;
+                    else {
+                        strcat(outputLine, " ");
+                        strcat(outputLine, options);
+                    }
+                    strfree(options);
+                }
+            }
+        }
+    }
+    if (error) {
+        fprintf(stderr, "serious libopt error prevented parsing library "
+                "names.  Invalid input to libopt is NOT the problem.\n");
+        retval = 10;
+    } else {
+        fputs(outputLine, stdout);
+        retval = 0;
+    }
+    return retval;
+}
diff --git a/buildtools/make_merge.sh b/buildtools/make_merge.sh
new file mode 100755
index 00000000..9043ad05
--- /dev/null
+++ b/buildtools/make_merge.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# This program is called by the make files.  It creates the merge.h
+# file which is included by netpbm.c.
+
+echo "/* File generated by make_merge.sh */"
+echo "/* in directory" `pwd` "*/"
+echo
+
+for MERGE_BINARY in $*; do
+    echo "TRY(\"${MERGE_BINARY}\", main_${MERGE_BINARY});"
+    done
diff --git a/buildtools/makecat b/buildtools/makecat
new file mode 100755
index 00000000..3a77a2a6
--- /dev/null
+++ b/buildtools/makecat
@@ -0,0 +1,18 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+my $TRUE=1; my $FALSE = 0;
+
+foreach my $htmlfilename (@ARGV) {
+    if ($htmlfilename =~ m{ (.*) \.html $ }x) {
+        my $basename = $1;
+
+        my $catfilename = "$basename.1";
+
+        print ("Converting $htmlfilename to $catfilename...\n");
+        system("lynx -dump $htmlfilename >$catfilename");
+    } else {
+        print ("Filename '$htmlfilename' doesn't end in 'html'.  Skipping.\n");
+    }
+}
diff --git a/buildtools/makeman b/buildtools/makeman
new file mode 100755
index 00000000..634a2c79
--- /dev/null
+++ b/buildtools/makeman
@@ -0,0 +1,333 @@
+#!/bin/env python
+#
+# makeman -- compile netpbm's stereotyped HTML to troff markup
+#
+# This approach works because we control the entire document universe 
+# this is going to convert and can reinforce useful stereotypes.
+#
+# The output of this tool uses cliches parseable by doclifter,
+# which should thus be able to recover all the semantic information
+# it looks like this thing is losing.
+#
+# Known bugs:
+#  * Ordered lists are smashed into unordered lists
+#
+# Limitations:
+#  * IMG tags are issued as .IMG preceded by a bolded caption containing
+#    the alt content.  This will only work if the page is formatted with
+#    mwww macros.
+#  * Loses summary information from tables.
+#  * Only permits one <HR> in the HTML, right before the index.
+#
+# Use the makeman: passthrough to insert format lines for tables.
+#
+# By Eric S. Raymond <esr@thyrsus.com>
+# Version 1.0, July 26 2004
+
+import os, sys, exceptions, re
+
+source = "netpbm documentation"
+section = 1
+
+warning = '''\
+.\" This man page was generated by the Netpbm tool 'makeman' from HTML source.
+.\" Do not hand-hack it!  If you have bug fixes or improvements, please find
+.\" the corresponding HTML page on the Netpbm website, generate a patch
+.\" against that, and send it to the Netpbm maintainer.
+'''
+
+class LiftException(exceptions.Exception):
+    def __init__(self, message, retval=1):
+        self.message = message
+        self.retval = retval
+
+def makeman(name, file, indoc):
+    "Transform a string representing an HTML document into man markup."
+    global section, sectmap
+    # Dot at left margin confuses troff.
+    # This program generates these,
+    indoc = indoc.replace("\n.", "\n@%@%@")
+    # Header-bashing
+    indoc = indoc.replace('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">\n',"")
+    indoc = indoc.replace('<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">', "")
+    indoc = indoc.replace('<?xml version="1.1" encoding="iso-8859-1" ?>\n',"")
+    indoc = indoc.replace('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "DTD/xhtml11.dtd">', "")
+    indoc = indoc.replace('<html xmlns="http://www.w3.org/1999/xhtml">', "")
+    indoc = indoc.replace("<HEAD>", "").replace("</HEAD>", "")
+    indoc = indoc.replace("<head>", "").replace("</head>", "")
+    indoc = re.sub('(?i)<A HREF="#index">Table Of Contents</A>', "", indoc)
+    datematch = re.compile("Updated: (.*)\n")
+    match = datematch.search(indoc)
+    if match:
+        date = match.group(1)
+    else:
+        date = ""
+    indoc = datematch.sub("", indoc)
+    namematch = re.compile("<H1>(.*)</H1>", re.I)
+    match = namematch.search(indoc)
+    if match:
+        name = match.group(1)
+    else:
+        name = None
+    section = 1
+    meta = re.compile('(?i)<META NAME="manual_section" CONTENT="([0-9])">')
+    match = meta.search(indoc)
+    if match:
+        section = int(match.group(1))
+        indoc = meta.sub("", indoc)
+    else:
+        section = sectmap.get(name, 0)
+    indoc = namematch.sub("", indoc)
+    indoc = re.sub("(?i)<BODY[^>]*>", "", indoc)
+    indoc = re.sub("(?i)<HTML>", "", indoc)
+    # Remove more superfluous headers
+    titlematch = re.compile("<TITLE>(.*)</TITLE>\n+", re.I)
+    match = titlematch.search(indoc)
+    if match:
+        title = match.group(1)
+    else:
+        title = None
+    indoc = titlematch.sub("", indoc)
+    indoc = re.sub("(?i)\n*<BR>\n+", "\n", indoc)
+    indoc = ('.TH "%s" %d "%s" "%s"\n' % (title,section,date,source)) + indoc
+    # Literal layout
+    indoc = re.sub("(?i)\n *<PRE>", "\n.nf", indoc)
+    indoc = re.sub("(?i)\n *</PRE>", "\n.fi", indoc)
+    indoc = re.sub("(?i)\n *<BLOCKQUOTE>", "\n.nf", indoc)
+    indoc = re.sub("(?i)\n *</BLOCKQUOTE>", "\n.fi", indoc)
+    # Highlight processing
+    indoc = re.sub("(?i)<B>", r"\\fB", indoc)
+    indoc = re.sub("(?i)</B>", r"\\fP", indoc)
+    indoc = re.sub("(?i)<EM>", r"\\fI", indoc)
+    indoc = re.sub("(?i)</EM>", r"\\fP", indoc)
+    indoc = re.sub("(?i)<CITE>", r"\\fI", indoc)
+    indoc = re.sub("(?i)</CITE>", r"\\fP", indoc)
+    indoc = re.sub("(?i)<I>", r"\\fI", indoc)
+    indoc = re.sub("(?i)</I>", r"\\fP", indoc)
+    indoc = re.sub("(?i)<TT>", r"\\f(CW", indoc)
+    indoc = re.sub("(?i)</TT>", r"\\fP", indoc)
+    indoc = re.sub("(?i)<KBD>", r"\\f(CW", indoc)
+    indoc = re.sub("(?i)</KBD>", r"\\fP", indoc)
+    indoc = re.sub("(?i)<STRONG>", r"\\fB", indoc)
+    indoc = re.sub("(?i)</STRONG>", r"\\fP", indoc)
+    indoc = re.sub("(?i)<SUP>", r"\\u", indoc)
+    indoc = re.sub("(?i)</SUP>", r"\\d", indoc)
+    # Paragraph handling
+    indoc = re.sub("(?i)\n*<P>\n*", r"\n.PP\n", indoc)
+    indoc = re.sub("(?i)</P>", "", indoc)
+    lines = indoc.split("\n")
+    listdepth = 0
+    for i in range(len(lines)):
+        lowered = lines[i].lower()
+        if "<dl" in lowered or "<ol" in lowered or "<ul" in lowered:
+            listdepth += 1
+        if listdepth:
+            lines[i] = lines[i].replace(".PP", ".sp")
+        if "</dl>" in lowered or "</ol>" in lowered or "</ul>" in lowered:
+            listdepth -= 1
+    indoc = "\n".join(lines)
+    indoc = re.sub(r"\s*\.sp", "\n.sp", indoc)
+    # Format email addresses as italic
+    indoc = re.sub('(?i)<A[ \n]+HREF="mailto:[^>]+">([^<]+)</A>', r'\\fI\1\\fP', indoc)    
+    # Format manual crossreferences
+    def xrefmatch(match):
+        xrefto = match.group(1)
+        xrefsection = sectmap.get(xrefto, 1)
+        if xrefsection == 0:
+            return "\n.I " + xrefto
+        else:
+            return "\n.BR %s (%d)" % (xrefto, xrefsection)
+    indoc = re.sub(r'(?i)\n* *(?:\\fB)?<A[ \n]+HREF="[^>]+.html">([^<]+)</A>(?:\\fP)?',
+                   xrefmatch, indoc)
+    # Format URLs
+    def urlmatch(match):
+        url = match.group(1).replace('\n', ' ')
+        txt = match.group(2).replace('\n', ' ')
+        return "\n.UR %s\n%s\n.UE\n\\&" % (url, txt)
+    indoc = re.sub(r'(?i)\n*(?:&lt;)?<A[ \n]+HREF *= *"([^>]+)">([^<]+)</A>(?:&gt;)?',
+                  urlmatch, indoc)
+    # Turn some entities into harmless cookies
+    indoc = indoc.replace("&lt;", "@#!#@").replace("&gt;", "#@!@#").replace("&amp;", "#!@!@!#")
+    indoc = indoc.replace("&#215;", r"\(mu")
+    indoc = indoc.replace("&#174;", r"\*R")
+    # Turn anchors into .UN tags
+    indoc = re.sub('(?i)<A NAME *= *"#?([a-zA-Z][a-zA-Z0-9.-]+)">(?:&nbsp;)*</A>\s*', ".UN \\1\n", indoc)
+    # Strip off the index trailer
+    trailer = re.compile('<HR */*>.*', re.DOTALL | re.IGNORECASE)
+    indoc = re.sub(trailer, "", indoc)
+    # If there was no index trailer, we still need to strip these
+    indoc = indoc.replace("</BODY>", "").replace("</HTML>", "")
+    indoc = indoc.replace("</body>", "").replace("</html>", "")
+    # Recognize sections with IDs
+    indoc = re.sub('(?i)<H2><A (?:ID|NAME)="([a-zA-Z]+)">([^><]*)</A></H2>',
+                   ".UN \\1\n.SH \\2", indoc)
+    indoc = re.sub('(?i)<H3><A (?:ID|NAME)="([a-zA-Z]+)">([^><]*)</A></H3>',
+                   ".UN \\1\n.SS \\2", indoc)
+    indoc = re.sub('(?i)<H4><A (?:ID|NAME)="([a-zA-Z]+)">([^><]*)</A></H4>',
+                   ".UN \\1\n.B \\2", indoc)
+    indoc = re.sub('(?i)<H2 (?:ID|NAME)="([a-zA-Z]+)">([^><]*)</H2>',
+                   ".UN \\1\n.SH \\2", indoc)
+    indoc = re.sub('(?i)<H3 (?:ID|NAME)="([a-zA-Z]+)">([^><]*)</H3>',
+                   ".UN \\1\n.SS \\2", indoc)
+    indoc = re.sub('(?i)<H4 (?:ID|NAME)="([a-zA-Z]+)">([^><]*)</H4>',
+                   ".UN \\1\n.B \\2", indoc)
+    # Sections without IDs
+    indoc = re.sub('(?i)<H2>([^><]*)</H2>', ".SH \\1", indoc)
+    indoc = re.sub('(?i)<H3>([^><]*)</H3>', ".SS \\1", indoc)
+    indoc = re.sub('(?i)<H4>([^><]*)</H4>', ".B \\1", indoc)
+    # 
+    # Process definition lists -- just turn them into .TPs
+    indoc = re.sub("(?i) *<DL *(COMPACT)?>", "", indoc)
+    indoc = re.sub("(?i) *</DL>", "", indoc)
+    indoc = re.sub("(?i) *<DT>", ".TP\n", indoc)
+    indoc = re.sub("(?i) *</DT>", "", indoc)
+    indoc = re.sub("(?i)\n*<DD>\n*", "\n", indoc)
+    indoc = re.sub("(?i) *</DD>", "", indoc)
+    # Process unordered lists -- just turn them into .TPs
+    indoc = re.sub("(?i)</?[UO]L *(COMPACT)?>", "", indoc)
+    indoc = re.sub("(?i) *<LI>", ".IP \(bu\n", indoc)
+    indoc = re.sub("(?i) *</LI>", "", indoc)
+    # No-print tags
+    indoc = re.sub("<!--no_print-->.*", "", indoc)
+    # Passthrough
+    indoc = re.sub(r"<\?makeman (.*) \?>", r'\1', indoc)
+    # Comments
+    indoc = re.sub("<!--([^-])*-->", r'.\"\1', indoc)
+    # Image tags
+    indoc = re.sub(' *<img src="([^"]*)" alt="([^"]*)"( *[a-z]*="?[0-9]*"?)*>', ".B \\2\n.IMG -C \\1", indoc)
+    # Special characters
+    indoc = indoc.replace("&quot;", "'")
+    indoc = indoc.replace("&nbsp;", "\\ ")
+    # Tables
+    indoc = re.sub(' *<table[^>]*>.*', ".TS", indoc)
+    indoc = re.sub(" *</table>.*", ".TE", indoc)
+    # First the single-line case
+    indoc = re.sub("</td> *<td>", "\t", indoc)
+    indoc = re.sub("<tr> *<td>", "", indoc)
+    indoc = re.sub("</td> *</tr>", "", indoc)
+    # Then the multiline case
+    indoc = re.sub(r'\s*<t[hd][^>]*>([^<\n]*)</t[dh]>\s*', '\t\\1', indoc)
+    indoc = re.sub(r'\s*<t[hd][^>]*>([^<]*)</t[dh]>\s*', '\tT{\n\\1T}', indoc)
+    indoc = indoc.replace("\n\\&T}", "\nT}")
+    indoc = re.sub(" *</tr>", "", indoc)
+    indoc = re.sub(" *<tr[^>]*>\t*", "", indoc)
+    indoc = re.sub(r"\.TS\s+<caption>([^<]*)</caption>\s*", ".B \\1\n.TS\n", indoc)
+    # Debugging
+    #sys.stderr.write("Name: %s, Title: %s, Date: %s\n" % (name, title, date))
+    # Time for error checking now
+    badlines = []
+    for line in indoc.split("\n"):
+        if "<" in line or ">" in line or re.search("&.*;", line):
+            badlines.append(line)
+    if badlines:
+        sys.stderr.write(("Bad lines from %s:\n-----------------\n" % file) + "\n".join(badlines) + "\n-----------------\n")
+    # Goes after bad-line check so we don't misinterpret it as an error
+    indoc = indoc.replace("@#!#@", "<").replace("#@!@#", ">").replace("#!@!@!#", "&")
+    indoc = re.sub("\n+$", "\n", indoc)
+    # Single-quote at left margin confuses troff.
+    # This program never generates these.
+    indoc = indoc.replace("\n'", "\n\\&'")
+    # Finish guarding against leading dots.
+    indoc = indoc.replace("\n@%@%@", "\n\\&.")
+    # Mark these generated pages so people won't hand-hack them.
+    indoc = warning + indoc
+    return indoc
+
+def main(args, mainout=sys.stdout, mainerr=sys.stderr):
+    global sectmap
+    import getopt
+    (options, arguments) = getopt.getopt(args, "v")
+    verbosity = 0
+    for (switch, val) in options:
+        if switch == '-v':
+            verbosity += 1
+    try:
+        # First pass: gather locations for crossreferences:
+        sectmap = {}
+        for file in arguments:
+            try: 
+                infp = open(file)
+            except:
+                sys.stderr.write("can't open %s" % name)
+                continue
+            indoc = infp.read()
+            infp.close()
+            namere = re.compile("<H1>(.*)</H1>", re.I)
+            namematch = namere.search(indoc)
+            titlere = re.compile("<TITLE>(.*)</TITLE>", re.I)
+            titlematch = titlere.search(indoc)
+            if not namematch:
+                raise LiftException("name missing from %s" % file)
+            if not titlematch:
+                raise LiftException("title missing from %s" % file)
+            else:
+                title = titlematch.group(1)
+                name = titlematch.group(1)
+            meta = re.compile('(?i)<META NAME="manual_section" CONTENT="([0-9])">')
+            match = meta.search(indoc)
+            if match:
+                section = int(match.group(1))
+                sectmap[title] = sectmap[file] = sectmap[name] = section
+            else:
+                sectmap[title] = sectmap[file] = sectmap[name] = 1
+            hr = re.compile("(?i)<HR>")
+            firsthr = hr.search(indoc)
+            if firsthr and hr.search(indoc[firsthr.start(0)+4:]):
+                LiftException("%s has two <HR> tags!" % file)
+        # Second pass: do formatting
+        for file in arguments:
+            try: 
+                infp = open(file)
+            except:
+                sys.stderr.write("can't open %s" % name)
+                continue
+            indoc = infp.read()
+            infp.close()
+            tempfile = file + ".~%s-%d~" % (name, os.getpid())
+            try:
+                outfp = open(tempfile, "w")
+            except OSError:
+                sys.stderr.write("%s: can't open tempfile" % name)
+                return True
+            try:
+                if verbosity:
+                    sys.stderr.write("makeman: %s\n" % file)
+                outdoc = makeman(name, file, indoc)
+            except:
+                os.remove(tempfile)
+                # Pass the exception upwards
+                (exc_type, exc_value, exc_traceback) = sys.exc_info()
+                raise exc_type, exc_value, exc_traceback
+            if outdoc == indoc:
+                os.remove(tempfile)
+            if outdoc is None:
+                continue
+            else:
+                outfp.write(outdoc)
+                outfp.close()	# under Windows you can't rename an open file
+                stem = file[:file.find(".")]
+                os.rename(tempfile, stem + "." + `sectmap[file]`)
+    except LiftException, e:
+        mainerr.write("makeman: " + e.message + "\n")
+        return e.retval
+    except IOError, e:
+        mainerr.write("makeman: file I/O error: %s\n" % e)
+        return 3
+    except KeyboardInterrupt:
+        mainerr.write("makeman: bailing out...\n")
+        return 4
+    except:
+        if verbosity:
+            (exc_type, exc_value, exc_traceback) = sys.exc_info()
+            raise exc_type, exc_value, exc_traceback
+        else:
+            return 5
+
+if __name__ == "__main__":
+    # Run the main sequence
+    raise SystemExit, main(sys.argv[1:])
+
+# The following sets edit modes for GNU EMACS
+# Local Variables:
+# mode:python
+# End:
diff --git a/buildtools/makepointerman b/buildtools/makepointerman
new file mode 100755
index 00000000..8fbb0f49
--- /dev/null
+++ b/buildtools/makepointerman
@@ -0,0 +1,91 @@
+#!/usr/bin/perl -w
+
+#############################################################################
+#                               makepointerman
+#############################################################################
+#
+# This program creates a Netpbm man page that says nothing except to use a
+# web browser to look at a particular URL.
+#
+# In Netpbm, we believe that man pages, and the Nroff/Troff formats, are
+# obsolete; that HTML and web browsers and the world wide web long ago replaced
+# them as the best way to deliver documentation.  However, documentation is 
+# useless when people don't know where it is.  People are very accustomed to
+# typing "man" to get information on a Unix program or library or file type,
+# so in the standard Netpbm installation, we install a conventional man page
+# for every command, library, and file type, but all it says is to use your
+# web browser to look at the real documentation.
+
+# What would be ideal is if the user simply had Manweb (or something like
+# it) installed as the 'man' command and configured to find the Netpbm
+# web documentation.
+
+# But because of the high probability that Netpbm installers will not 
+# install Manweb, pointer man pages are necessary.
+
+# Besides making the web documentation accessible, pointer man pages serve
+# another important purpose:  Installing them causes obsolete man pages from
+# before web documentation existed to be discarded.
+
+use strict;
+use Time::gmtime;
+
+if (@ARGV < 5) {
+    die("Need 6 arguments: filename, directory URL, man page directory, " .
+        "man section, format, octal permissions");
+}
+
+my ($filename, $directoryUrl, $mandir, $section, $format, $permissions) = 
+    @ARGV;
+
+if ($format ne "nroff" && $format ne "cat") {
+    die("format argument must be 'nroff' or 'cat', not '$format'.");
+}
+my $manPageFileName = "$mandir/$filename.$section";
+
+unlink($manPageFileName);
+
+open(MANPAGE, ">$manPageFileName") or
+    die("Unable to create file '$manPageFileName'");
+
+my ($wday, $mon, $mday, $tod, $year) = split(/ /,gmctime());
+if ($format eq "nroff") {
+    print(MANPAGE ".TH $filename $section Netpbm \"$mday $mon $year\" " .
+          "\"Netpbm pointer man pages\"\n\n");
+    
+    # NAME and DESCRIPTION section headings help some automated processors,
+    # such as Doclifter.  From ESR 2004.11.14.
+
+    # avoid a double slash in the URL
+    (my $cleanedUpDirectoryUrl = $directoryUrl) =~ s{^(.*?)/*$}{$1};
+
+    print(MANPAGE ".SH NAME\n");
+    print(MANPAGE "$filename \\- see $cleanedUpDirectoryUrl/$filename.html\n");
+    print(MANPAGE ".SH DESCRIPTION\n");
+} else {
+    print(MANPAGE "        NETPBM POINTER MAN PAGES       \n\n");
+}
+print(MANPAGE "$filename is part of the Netpbm package.\n");
+print(MANPAGE "Netpbm documentation is kept in HTML format.\n");
+print(MANPAGE "\n");
+print(MANPAGE "Please refer to <$directoryUrl/$filename.html>.\n\n");
+print(MANPAGE "If that doesn't work, also try " .
+      "<http://netpbm.sourceforge.net> and\n");
+print(MANPAGE "emailing Bryan Henderson, bryanh\@giraffe-data.com.\n");
+
+print(MANPAGE "\n");
+print(MANPAGE "Note that making the documentation available this way was\n");
+print(MANPAGE "a choice of the person who installed Netpbm on this system.\n");
+print(MANPAGE "It is also possible to install Netpbm such that you would\n");
+print(MANPAGE "simply see the documentation instead of the message you are\n");
+print(MANPAGE "reading now.\n");
+print(MANPAGE "\n");
+
+if ($format eq "nroff") {
+    print(MANPAGE ".\\\" This file was generated by the program " .
+          "'makepointerman',\n");
+    print(MANPAGE ".\\\" as part of Netpbm installation\n");
+}
+
+chmod(oct("0$permissions"),$manPageFileName);
+close(MANPAGE);
diff --git a/buildtools/mkinstalldirs b/buildtools/mkinstalldirs
new file mode 100755
index 00000000..2c5ab7cb
--- /dev/null
+++ b/buildtools/mkinstalldirs
@@ -0,0 +1,41 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain
+
+# This program is important because some systems don't have an 'install'
+# program that has the -d option to create directories.
+
+errstatus=0
+
+for file
+do
+   set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+   shift
+
+   pathcomp=
+   for d
+   do
+     pathcomp="$pathcomp$d"
+     case "$pathcomp" in
+       -* ) pathcomp=./$pathcomp ;;
+     esac
+
+     if test ! -d "$pathcomp"; then
+        echo "mkdir $pathcomp"
+
+        mkdir "$pathcomp" || lasterr=$?
+
+        if test ! -d "$pathcomp"; then
+  	  errstatus=$lasterr
+        fi
+     fi
+
+     pathcomp="$pathcomp/"
+   done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
diff --git a/buildtools/stamp-date b/buildtools/stamp-date
new file mode 100755
index 00000000..808bab79
--- /dev/null
+++ b/buildtools/stamp-date
@@ -0,0 +1,23 @@
+#!/bin/sh
+#
+# Copyright (C) 1993 by Oliver Trepte.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose and without fee is hereby granted, provided
+# that the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation.  This software is provided "as is" without express or
+# implied warranty.
+#
+DATE=`date`
+LOGNAME_OR_UNKNOWN=${LOGNAME:-UNKNOWN}
+USER=${USER:-$LOGNAME_OR_UNKNOWN}
+if [ $USER = "UNKNOWN" ]; then
+    USER=`whoami`
+fi
+
+echo "/* This file tells the package when it was compiled */"
+echo "/* DO NOT EDIT - THIS FILE IS MAINTAINED AUTOMATICALLY */"
+echo "/* Created by the program 'stamp-date'  */"
+echo "#define COMPILE_TIME \"$DATE\""
+echo "#define COMPILED_BY \"$USER\""
diff --git a/buildtools/typegen b/buildtools/typegen
new file mode 100755
index 00000000..b76191f3
--- /dev/null
+++ b/buildtools/typegen
Binary files differdiff --git a/buildtools/typegen.c b/buildtools/typegen.c
new file mode 100644
index 00000000..5b32af28
--- /dev/null
+++ b/buildtools/typegen.c
@@ -0,0 +1,113 @@
+/*----------------------------------------------------------------------------
+                                 typegen
+------------------------------------------------------------------------------
+  This is a program to create an inttypes.h file for use in building
+  Netpbm.  Ordinarily we use the inttypes.h that comes with the C library
+  or C compiler, specified by Single Unix Specification.  When that isn't
+  available there is usually some other system header file we should use.
+  But when there isn't any system header file to define the needed types,
+  the file we generate is better than nothing.
+
+  The main problem with the inttypes.h we generate is that when we
+  figure out which type is a 32 bit integer, we aren't necessarily using
+  the same compile environment as what will actually get used to build
+  Netpbm, and thus the one where our inttypes.h will be used.
+
+  Right now, it simply generates either 
+  
+    typedef int int32_t;
+
+  or
+
+    typedef long int32_t;
+
+  based on which type, int, or long, is 32 bits.
+
+  We also include the uint32_t and int_fast32_t typedefs.
+
+  We also include the multiple inclusion guard ifdef.
+-----------------------------------------------------------------------------*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+
+
+static void
+createTypedefForUint32_t(void) {
+
+    if (sizeof(unsigned int) == 4)
+        printf("typedef unsigned int uint32_t;\n");
+    else if (sizeof(unsigned long) == 4)
+        printf("typedef unsigned long uint32_t;\n");
+    else {
+        fprintf(stderr, "Cannot find a 32 bit unsigned integer type!\n");
+        exit(1);
+    }
+}
+
+
+
+static void
+createTypedefForUintFast32_t(void) {
+
+    if (sizeof(unsigned int) == 4)
+        printf("typedef unsigned int uint_fast32_t;\n");
+    else if (sizeof(unsigned long) == 4)
+        printf("typedef unsigned long uint_fast32_t;\n");
+    else {
+        fprintf(stderr, "Cannot find a 32 bit unsigned integer type!\n");
+        exit(1);
+    }
+}
+
+
+
+static void
+createTypedefForInt32_t(void) {
+
+    if (sizeof(signed int) == 4)
+        printf("typedef signed int int32_t;\n");
+    else if (sizeof(signed long) == 4)
+        printf("typedef signed long int32_t;\n");
+    else {
+        fprintf(stderr, "Cannot find a 32 bit signed integer type!\n");
+        exit(1);
+    }
+}
+
+
+
+static void
+createTypedefForIntFast32_t(void) {
+
+    if (sizeof(signed int) == 4)
+        printf("typedef signed int int_fast32_t;\n");
+    else if (sizeof(signed long) == 4)
+        printf("typedef signed long int_fast32_t;\n");
+    else {
+        fprintf(stderr, "Cannot find a 32 bit signed integer type!\n");
+        exit(1);
+    }
+}
+
+
+
+int
+main(int argc, char **argv) {
+
+    printf("/* This was generated by the program 'typegen' */\n");
+
+
+    printf("#ifndef INTTYPES_H_NETPBM\n");
+    printf("#define INTTYPES_H_NETPBM\n");
+
+    createTypedefForUint32_t();
+    createTypedefForInt32_t();
+    createTypedefForIntFast32_t();
+    createTypedefForUintFast32_t();
+
+    printf("#endif\n");
+
+    return 0;
+}