--- /dev/null
+Makefile.in
+acinclude.m4
+aclocal.m4
+config.h.in
+configure
+dlife.spec
+dlife-*.tar.gz
+index.html
+dlife_client.pl
+dlife_server.pl
+install-sh
+missing
+mkinstalldirs
+stamp-h.in
+config.cache
+config.h
+config.log
+config.status
+dlife_soup
+stamp-h
+Makefile
+.deps
--- /dev/null
+Richard Jones <rich@annexia.org>
+ * Main author and maintainer.
+
+Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
+ * Contributed Debian package.
--- /dev/null
+#!/bin/sh -
+# DLIFE (C) 2000 Richard W.M. Jones <rich@annexia.org>
+# and other authors listed in the ``AUTHORS'' file.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# $Id: Build,v 1.1 2002/04/05 17:02:25 rich Exp $
+
+# This is a highly specialized build script for my machine. You will
+# probably need to change this substantially to be appropriate for
+# your environment.
+#
+# Please note also that you normally only ever run this script if you
+# have changed something about the build process itself -- for example
+# if you have changed ``configure.in'' or one of the ``Makefile.am''
+# files. If you just want to do a normal rebuild after changing a
+# source file, all you need to do is:
+#
+# make && make install
+#
+# - RWMJ 1999/12/27.
+
+set -e
+set -v
+
+: Make clean
+make distclean ||:
+
+: Rebuilding autoconf/automake files
+aclocal
+autoheader
+automake
+autoconf
+
+mkdir -p $HOME/.build/{usr/share/doc,etc/cron.d,etc/init.d,var} ||:
+
+: Configure.
+CFLAGS="-O" \
+./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var \
+ --disable-user-check
+
+: Build.
+make
+
+: Now run 'make install' as root.
--- /dev/null
+#!/bin/sh -
+# DLIFE (C) 2000 Richard W.M. Jones <rich@annexia.org>
+# and other authors listed in the ``AUTHORS'' file.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# $Id: Build.local,v 1.2 2002/04/05 17:02:25 rich Exp $
+
+# This is a highly specialized build script for my machine. You will
+# probably need to change this substantially to be appropriate for
+# your environment.
+#
+# Please note also that you normally only ever run this script if you
+# have changed something about the build process itself -- for example
+# if you have changed ``configure.in'' or one of the ``Makefile.am''
+# files. If you just want to do a normal rebuild after changing a
+# source file, all you need to do is:
+#
+# make && make install
+#
+# - RWMJ 1999/12/27.
+
+set -e
+set -v
+
+: Make clean
+make distclean ||:
+
+: Rebuilding autoconf/automake files
+aclocal
+autoheader
+automake
+autoconf
+
+mkdir -p $HOME/.build/{usr/share/doc,etc/cron.d,etc/init.d,var} ||:
+
+: Configure.
+CFLAGS="-O" \
+./configure \
+ --prefix=$HOME/.build/usr \
+ --sysconfdir=$HOME/.build/etc \
+ --localstatedir=$HOME/.build/var
+
+: Build.
+make
+
+: Install in local build directory
+make NO_CHOWN=1 install
+
+: Now run it with: $HOME/.build/usr/bin/dlife_soup
--- /dev/null
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
--- /dev/null
+2002-12-10 Nix <nix@esperi.demon.co.uk>
+
+ * main.c (main): Use LOG_DAEMON, not LOG_USER.
+ * main.c (detect_nr_cpus): New for SPARC/Linux.
+
+ * cell.c (run_thread): Use syslog(), not printf().
+ * cell.c (cell_state_load): Likewise.
+ * cell.c (_cell_fixup_soup_ref): Likewise.
+ * cell.c (save_cell_in_outgoing): Likewise.
--- /dev/null
+Distributed Artificial Life (DLIFE) Installation Instructions
+-------------------------------------------------------------
+
+Prerequisites
+-------------
+
+For security reasons, all programs run as user/group dlife/dlife. Therefore
+in order to be able to install this program, you must first create a user
+and group called `dlife'. On a typical Linux system you will need to
+do this, as root, before installing:
+
+ /usr/sbin/groupadd dlife
+ /usr/sbin/useradd -g dlife -M dlife
+
+You will need the following Perl packages installed. Get them from
+CPAN (http://www.cpan.org/) or one of its mirrors, or else get RPMs
+from http://dlife.annexia.org/files/ .
+
+ libnet, HTML-Parser, URI, MIME-Base64, Digest-MD5, libwww-perl,
+ Getopt-Long
+
+Warning to non-Red Hat users
+----------------------------
+
+The current installation is very Red Hat / Debian specific. It
+installs files under /etc/cron.d/ and /etc/init.d/ directories, which
+probably only exist on Red Hat or Debian machines. It would be nice to
+have a way to determine where these directories are and to
+automagically install cron jobs and rc files in the appropriate
+places. Can anyone help me with this?
+
+Building and installing the client from source
+----------------------------------------------
+
+Configure the software:
+
+ ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var
+
+Check that the software is going to be installed in the right
+places. On my Red Hat Linux boxen, I get:
+
+ checking for crontab directory... /etc/cron.d
+ checking for rc directory... /etc/init.d
+ checking spool directory... /var/spool/dlife
+ checking config directory... /etc/dlife
+
+Build it:
+
+ make
+
+Install it (as root):
+
+ make install
+
+To start up the software, run the following command as root:
+
+ /etc/init.d/dlife.rc
+
+If all went well, then you should see one of more ``dlife_soup''
+processes running in top. (There should be one process for each
+CPU on your machine).
+
+To make the dlife client start up every time you reboot the
+computer, do as root:
+
+ /sbin/chkconfig --add dlife.rc
+
+A cron job is set to run every hour which exchanges cells with
+your local dlife server. By default it runs at 5 minutes past
+the hour, but to avoid causing load spikes on dlife servers at
+this time, it's best to edit the cron script and change the
+time at which it runs. This script is here:
+
+ /etc/cron.d/dlife_client.cron
+
+If you're running behind a firewall, then you may want to run a
+server (see next section). In that case, you need to edit the
+following file to list the location of your server(s):
+
+ /etc/dlife/client.conf
+
+Building and installing the server from source
+----------------------------------------------
+
+Follow the process above, as if you were installing the client.
+
+Edit /etc/inetd.conf and add the following line:
+
+ 5904 stream tcp nowait root /usr/sbin/tcpd /usr/bin/dlife_server.pl
+
+Restart inetd:
+
+ killall -HUP inetd
+
+Building RPMs
+-------------
+
+To build RPMs from the sources:
+
+ ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var \
+ --disable-user-check
+ make
+ make dist
+ rpm -ta --clean dlife-X.Y.Z.tar.gz
+
+(where X.Y.Z is the current version of dlife).
--- /dev/null
+# -*- Makefile -*-
+#
+# This is a make+ file. Make+ is a set of scripts which enhance GNU
+# make and let you build RPMs, and other package types with just one
+# control file. To build this package you will need to download make+
+# from this site: http://www.annexia.org/freeware/makeplus/
+
+PACKAGE := dlife
+VERSION_MAJOR := 1
+VERSION_MINOR := 1.0
+VERSION := $(VERSION_MAJOR).$(VERSION_MINOR)
+
+SUMMARY := Distributed artificial life
+COPYRIGHT := GPL
+AUTHOR := Richard W.M. Jones <rich@annexia.org>
+
+define DESCRIPTION
+Distributed Artificial Life is a package for joining your
+computer to a network of computers running a large artificial
+life simulation.
+endef
+
+RPM_REQUIRES := perl-libwww-perl, perl >= 5.004, vixie-cron, SysVinit
+RPM_GROUP := Applications/Internet
+
+spooldir = $(localstatedir)/spool/dlife
+confdir = $(sysconfdir)/dlife
+crondir = $(sysconfdir)/cron.d
+rcdir = $(sysconfdir)/init.d
+
+CFLAGS += -Wall -Werror -g -O2 \
+ -DCONFDIR=\"$(confdir)\" \
+ -DSPOOLDIR=\"$(spooldir)\"
+#LIBS +=
+
+ifdef ENABLE_CHECK
+CFLAGS += -DCHECK=1
+endif
+
+ifdef ENABLE_PROFILE
+CFLAGS += -pg
+endif
+
+DOCS := $(srcdir)/AUTHORS $(srcdir)/INSTALL $(srcdir)/README \
+ $(srcdir)/archproc.gif $(srcdir)/archproc.fig \
+ $(srcdir)/archref.html $(srcdir)/index.html \
+ $(srcdir)/machineref.html
+
+OBJS := cell.o crc.o exec.o image.o load.o main.o random.o soup.o state.o
+
+all: build
+
+configure:
+ $(MP_CONFIGURE_START)
+ $(MP_CHECK_HEADERS) assert.h dirent.h errno.h fcntl.h grp.h pwd.h \
+ signal.h stddef.h stdint.h string.h sys/param.h sys/types.h \
+ syslog.h time.h unistd.h
+ $(MP_CHECK_FUNCS) closedir getpwnam getuid initgroups nice opendir \
+ openlog readdir setgid setuid syslog
+ifndef DISABLE_USER_CHECK
+# $(MP_CHECK_USER_GROUP) dlife dlife
+endif
+ $(MP_CONFIGURE_END)
+
+build: dlife_soup
+
+dlife_soup: $(OBJS)
+ $(CC) $(CFLAGS) $^ $(LIBS) -o $@
+
+test:
+
+install:
+ install -d $(DESTDIR)$(bindir)
+ install -d $(DESTDIR)$(docdir)
+ install -d $(DESTDIR)$(spooldir)
+ install -d $(DESTDIR)$(spooldir)/incoming
+ install -d $(DESTDIR)$(spooldir)/outgoing
+ install -d $(DESTDIR)$(spooldir)/saved
+ install -d $(DESTDIR)$(spooldir)/store
+ install -d $(DESTDIR)$(confdir)
+ install -d $(DESTDIR)$(crondir)
+ install -d $(DESTDIR)$(rcdir)
+
+ install -m 0755 dlife_soup $(srcdir)/dlife_client.pl \
+ $(srcdir)/dlife_server.pl $(DESTDIR)$(bindir)
+ install -m 0644 $(DOCS) $(DESTDIR)$(docdir)
+ install -m 0644 god.dlo $(DESTDIR)$(spooldir)
+ install -m 0644 $(srcdir)/client.conf $(srcdir)/soup.conf \
+ $(DESTDIR)$(confdir)
+ install -m 0644 $(srcdir)/dlife_client.cron $(DESTDIR)$(crondir)
+ install -m 0644 $(srcdir)/dlife.rc $(DESTDIR)$(rcdir)
+
+ chown -R dlife.dlife $(DESTDIR)$(spooldir) ||:
+
+define WEBSITE
+<html>
+XXX PUT YOUR WEBSITE HERE. IF YOU DON\'T WANT TO MANAGE A WEBSITE WITH
+XXX MAKE+ THEN JUST DELETE THIS SECTION AND THE upload_website RULE.
+</html>
+endef
+
+upload_website:
+ scp $(PACKAGE)-$(VERSION).tar.gz $(PACKAGE)-$(VERSION)-1.*.rpm \
+ $(PACKAGE)-$(VERSION).bin.tar.gz \
+ you@yourmachine.example.com:/var/www/html/$(PACKAGE)/files
+ scp index.html you@yourmachine.example.com:/var/www/html/$(PACKAGE)/
+
+.PHONY: build configure test upload_website
--- /dev/null
+# DLIFE (C) 2000 Richard W.M. Jones <rich@annexia.org>
+# and other authors listed in the ``AUTHORS'' file.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# $Id: Makefile.am,v 1.3 2002/04/05 17:20:11 rich Exp $
+
+AUTOMAKE_OPTIONS = foreign
+
+EXTRA_DIST = .cvsignore \
+ Build \
+ Build.local \
+ dlife_asm.pl \
+ dlife_client.pl.in \
+ dlife_disasm.pl \
+ dlife_server.pl.in \
+ dlife.spec \
+ dlife.spec.in \
+ god.dla \
+ index.html.in \
+ servers.txt \
+ debian/changelog \
+ debian/conffiles \
+ debian/control \
+ debian/copyright \
+ debian/cron.d \
+ debian/dirs \
+ debian/docs \
+ debian/files \
+ debian/init.d \
+ debian/postinst.debhelper \
+ debian/postrm.debhelper \
+ debian/prerm.debhelper \
+ debian/rules \
+ debian/substvars \
+ $(bin_SCRIPTS) \
+ $(conf_DATA) \
+ $(cron_DATA) \
+ $(doc_DATA) \
+ $(rc_SCRIPTS) \
+ $(spool_DATA)
+
+docdir = @DOCDIR@
+doc_DATA = AUTHORS \
+ INSTALL \
+ README \
+ archproc.gif \
+ archproc.fig \
+ archref.html \
+ index.html \
+ machineref.html
+
+spooldir = @SPOOLDIR@
+spool_DATA = god.dlo
+
+confdir = @CONFDIR@
+conf_DATA = client.conf soup.conf
+
+if INSTALL_CRON
+crondir = @CRONDIR@
+else
+crondir = /tmp
+endif
+cron_DATA = dlife_client.cron
+
+if INSTALL_RC
+rcdir = @RCDIR@
+else
+rcdir = /tmp
+endif
+rc_SCRIPTS = dlife.rc
+
+bin_PROGRAMS = dlife_soup
+
+bin_SCRIPTS = dlife_client.pl dlife_server.pl
+
+dlife_soup_SOURCES = \
+ cell.c \
+ cell.h \
+ crc.c \
+ crc.h \
+ dlink.h \
+ exec.c \
+ image.c \
+ image.h \
+ load.c \
+ load.h \
+ main.c \
+ params.h \
+ random.c \
+ random.h \
+ soup.c \
+ soup.h \
+ state.c \
+ state.h \
+ types.h
+
+install-data-hook:
+ $(mkinstalldirs) $(DESTDIR)$(spooldir)/incoming
+ $(mkinstalldirs) $(DESTDIR)$(spooldir)/outgoing
+ $(mkinstalldirs) $(DESTDIR)$(spooldir)/saved
+ $(mkinstalldirs) $(DESTDIR)$(spooldir)/store
+ ifndef NO_CHOWN
+ chown -R dlife.dlife $(DESTDIR)$(spooldir)
+ endif
--- /dev/null
+# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# DLIFE (C) 2000 Richard W.M. Jones <rich@annexia.org>
+# and other authors listed in the ``AUTHORS'' file.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# $Id: Makefile.am,v 1.3 2002/04/05 17:20:11 rich Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = .
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+CC = @CC@
+CONFDIR = @CONFDIR@
+CRONDIR = @CRONDIR@
+DOCDIR = @DOCDIR@
+MAKEINFO = @MAKEINFO@
+PACKAGE = @PACKAGE@
+RCDIR = @RCDIR@
+RELEASEDATE = @RELEASEDATE@
+SPOOLDIR = @SPOOLDIR@
+VERSION = @VERSION@
+
+AUTOMAKE_OPTIONS = foreign
+
+EXTRA_DIST = .cvsignore Build Build.local dlife_asm.pl dlife_client.pl.in dlife_disasm.pl dlife_server.pl.in dlife.spec dlife.spec.in god.dla index.html.in servers.txt debian/changelog debian/conffiles debian/control debian/copyright debian/cron.d debian/dirs debian/docs debian/files debian/init.d debian/postinst.debhelper debian/postrm.debhelper debian/prerm.debhelper debian/rules debian/substvars $(bin_SCRIPTS) $(conf_DATA) $(cron_DATA) $(doc_DATA) $(rc_SCRIPTS) $(spool_DATA)
+
+
+docdir = @DOCDIR@
+doc_DATA = AUTHORS INSTALL README archproc.gif archproc.fig archref.html index.html machineref.html
+
+
+spooldir = @SPOOLDIR@
+spool_DATA = god.dlo
+
+confdir = @CONFDIR@
+conf_DATA = client.conf soup.conf
+@INSTALL_CRON_TRUE@crondir = @CRONDIR@
+@INSTALL_CRON_FALSE@crondir = /tmp
+cron_DATA = dlife_client.cron
+@INSTALL_RC_TRUE@rcdir = @RCDIR@
+@INSTALL_RC_FALSE@rcdir = /tmp
+rc_SCRIPTS = dlife.rc
+
+bin_PROGRAMS = dlife_soup
+
+bin_SCRIPTS = dlife_client.pl dlife_server.pl
+
+dlife_soup_SOURCES = cell.c cell.h crc.c crc.h dlink.h exec.c image.c image.h load.c load.h main.c params.h random.c random.h soup.c soup.h state.c state.h types.h
+
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES = dlife_client.pl dlife_server.pl dlife.spec \
+index.html
+PROGRAMS = $(bin_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I.
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+dlife_soup_OBJECTS = cell.o crc.o exec.o image.o load.o main.o random.o \
+soup.o state.o
+dlife_soup_LDADD = $(LDADD)
+dlife_soup_DEPENDENCIES =
+dlife_soup_LDFLAGS =
+SCRIPTS = $(bin_SCRIPTS) $(rc_SCRIPTS)
+
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DATA = $(conf_DATA) $(cron_DATA) $(doc_DATA) $(spool_DATA)
+
+DIST_COMMON = README ./stamp-h.in AUTHORS COPYING INSTALL Makefile.am \
+Makefile.in acconfig.h aclocal.m4 config.h.in configure configure.in \
+dlife.spec.in dlife_client.pl.in dlife_server.pl.in index.html.in \
+install-sh missing mkinstalldirs
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+DEP_FILES = .deps/cell.P .deps/crc.P .deps/exec.P .deps/image.P \
+.deps/load.P .deps/main.P .deps/random.P .deps/soup.P .deps/state.P
+SOURCES = $(dlife_soup_SOURCES)
+OBJECTS = $(dlife_soup_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .o .s
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
+ cd $(top_builddir) \
+ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(ACLOCAL_M4): configure.in
+ cd $(srcdir) && $(ACLOCAL)
+
+config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+ cd $(srcdir) && $(AUTOCONF)
+
+config.h: stamp-h
+ @if test ! -f $@; then \
+ rm -f stamp-h; \
+ $(MAKE) stamp-h; \
+ else :; fi
+stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES= CONFIG_HEADERS=config.h \
+ $(SHELL) ./config.status
+ @echo timestamp > stamp-h 2> /dev/null
+$(srcdir)/config.h.in: $(srcdir)/stamp-h.in
+ @if test ! -f $@; then \
+ rm -f $(srcdir)/stamp-h.in; \
+ $(MAKE) $(srcdir)/stamp-h.in; \
+ else :; fi
+$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h
+ cd $(top_srcdir) && $(AUTOHEADER)
+ @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null
+
+mostlyclean-hdr:
+
+clean-hdr:
+
+distclean-hdr:
+ -rm -f config.h
+
+maintainer-clean-hdr:
+dlife_client.pl: $(top_builddir)/config.status dlife_client.pl.in
+ cd $(top_builddir) && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+dlife_server.pl: $(top_builddir)/config.status dlife_server.pl.in
+ cd $(top_builddir) && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+dlife.spec: $(top_builddir)/config.status dlife.spec.in
+ cd $(top_builddir) && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+index.html: $(top_builddir)/config.status index.html.in
+ cd $(top_builddir) && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+mostlyclean-binPROGRAMS:
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+distclean-binPROGRAMS:
+
+maintainer-clean-binPROGRAMS:
+
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(bin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+dlife_soup: $(dlife_soup_OBJECTS) $(dlife_soup_DEPENDENCIES)
+ @rm -f dlife_soup
+ $(LINK) $(dlife_soup_LDFLAGS) $(dlife_soup_OBJECTS) $(dlife_soup_LDADD) $(LIBS)
+
+install-binSCRIPTS: $(bin_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_SCRIPTS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \
+ $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \
+ else if test -f $(srcdir)/$$p; then \
+ echo " $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \
+ $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \
+ else :; fi; fi; \
+ done
+
+uninstall-binSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ list='$(bin_SCRIPTS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \
+ done
+
+install-rcSCRIPTS: $(rc_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(rcdir)
+ @list='$(rc_SCRIPTS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(INSTALL_SCRIPT) $$p $(DESTDIR)$(rcdir)/`echo $$p|sed '$(transform)'`"; \
+ $(INSTALL_SCRIPT) $$p $(DESTDIR)$(rcdir)/`echo $$p|sed '$(transform)'`; \
+ else if test -f $(srcdir)/$$p; then \
+ echo " $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(rcdir)/`echo $$p|sed '$(transform)'`"; \
+ $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(rcdir)/`echo $$p|sed '$(transform)'`; \
+ else :; fi; fi; \
+ done
+
+uninstall-rcSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ list='$(rc_SCRIPTS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(rcdir)/`echo $$p|sed '$(transform)'`; \
+ done
+
+install-confDATA: $(conf_DATA)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(confdir)
+ @list='$(conf_DATA)'; for p in $$list; do \
+ if test -f $(srcdir)/$$p; then \
+ echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(confdir)/$$p"; \
+ $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(confdir)/$$p; \
+ else if test -f $$p; then \
+ echo " $(INSTALL_DATA) $$p $(DESTDIR)$(confdir)/$$p"; \
+ $(INSTALL_DATA) $$p $(DESTDIR)$(confdir)/$$p; \
+ fi; fi; \
+ done
+
+uninstall-confDATA:
+ @$(NORMAL_UNINSTALL)
+ list='$(conf_DATA)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(confdir)/$$p; \
+ done
+
+install-cronDATA: $(cron_DATA)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(crondir)
+ @list='$(cron_DATA)'; for p in $$list; do \
+ if test -f $(srcdir)/$$p; then \
+ echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(crondir)/$$p"; \
+ $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(crondir)/$$p; \
+ else if test -f $$p; then \
+ echo " $(INSTALL_DATA) $$p $(DESTDIR)$(crondir)/$$p"; \
+ $(INSTALL_DATA) $$p $(DESTDIR)$(crondir)/$$p; \
+ fi; fi; \
+ done
+
+uninstall-cronDATA:
+ @$(NORMAL_UNINSTALL)
+ list='$(cron_DATA)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(crondir)/$$p; \
+ done
+
+install-docDATA: $(doc_DATA)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(docdir)
+ @list='$(doc_DATA)'; for p in $$list; do \
+ if test -f $(srcdir)/$$p; then \
+ echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(docdir)/$$p"; \
+ $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(docdir)/$$p; \
+ else if test -f $$p; then \
+ echo " $(INSTALL_DATA) $$p $(DESTDIR)$(docdir)/$$p"; \
+ $(INSTALL_DATA) $$p $(DESTDIR)$(docdir)/$$p; \
+ fi; fi; \
+ done
+
+uninstall-docDATA:
+ @$(NORMAL_UNINSTALL)
+ list='$(doc_DATA)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(docdir)/$$p; \
+ done
+
+install-spoolDATA: $(spool_DATA)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(spooldir)
+ @list='$(spool_DATA)'; for p in $$list; do \
+ if test -f $(srcdir)/$$p; then \
+ echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(spooldir)/$$p"; \
+ $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(spooldir)/$$p; \
+ else if test -f $$p; then \
+ echo " $(INSTALL_DATA) $$p $(DESTDIR)$(spooldir)/$$p"; \
+ $(INSTALL_DATA) $$p $(DESTDIR)$(spooldir)/$$p; \
+ fi; fi; \
+ done
+
+uninstall-spoolDATA:
+ @$(NORMAL_UNINSTALL)
+ list='$(spool_DATA)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(spooldir)/$$p; \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags -o $$here/TAGS $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP))
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ -rm -rf $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
+ mkdir $(distdir)/=build
+ mkdir $(distdir)/=inst
+ dc_install_base=`cd $(distdir)/=inst && pwd`; \
+ cd $(distdir)/=build \
+ && ../configure --srcdir=.. --prefix=$$dc_install_base \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) dist
+ -rm -rf $(distdir)
+ @banner="$(distdir).tar.gz is ready for distribution"; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"
+dist: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+dist-all: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+distdir: $(DISTFILES)
+ -rm -rf $(distdir)
+ mkdir $(distdir)
+ -chmod 777 $(distdir)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign Makefile
+ $(mkinstalldirs) $(distdir)/debian
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$d/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+all-recursive-am: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+install-exec-am: install-binPROGRAMS install-binSCRIPTS
+install-exec: install-exec-am
+
+install-data-am: install-rcSCRIPTS install-confDATA install-cronDATA \
+ install-docDATA install-spoolDATA
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-data-hook
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
+ uninstall-rcSCRIPTS uninstall-confDATA \
+ uninstall-cronDATA uninstall-docDATA \
+ uninstall-spoolDATA
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS) $(SCRIPTS) $(DATA) config.h
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(bindir) \
+ $(DESTDIR)$(rcdir) $(DESTDIR)$(confdir) \
+ $(DESTDIR)$(crondir) $(DESTDIR)$(docdir) \
+ $(DESTDIR)$(spooldir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-hdr mostlyclean-binPROGRAMS \
+ mostlyclean-compile mostlyclean-tags mostlyclean-depend \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-hdr clean-binPROGRAMS clean-compile clean-tags \
+ clean-depend clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-hdr distclean-binPROGRAMS distclean-compile \
+ distclean-tags distclean-depend distclean-generic \
+ clean-am
+
+distclean: distclean-am
+ -rm -f config.status
+
+maintainer-clean-am: maintainer-clean-hdr maintainer-clean-binPROGRAMS \
+ maintainer-clean-compile maintainer-clean-tags \
+ maintainer-clean-depend maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+ -rm -f config.status
+
+.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
+mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
+maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile uninstall-binSCRIPTS install-binSCRIPTS \
+uninstall-rcSCRIPTS install-rcSCRIPTS uninstall-confDATA \
+install-confDATA uninstall-cronDATA install-cronDATA uninstall-docDATA \
+install-docDATA uninstall-spoolDATA install-spoolDATA tags \
+mostlyclean-tags distclean-tags clean-tags maintainer-clean-tags \
+distdir mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check check-am \
+installcheck-am installcheck all-recursive-am install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+install-data-hook:
+ $(mkinstalldirs) $(DESTDIR)$(spooldir)/incoming
+ $(mkinstalldirs) $(DESTDIR)$(spooldir)/outgoing
+ $(mkinstalldirs) $(DESTDIR)$(spooldir)/saved
+ $(mkinstalldirs) $(DESTDIR)$(spooldir)/store
+ ifndef NO_CHOWN
+ chown -R dlife.dlife $(DESTDIR)$(spooldir)
+ endif
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+Distributed Artificial Life (DLIFE)
+-----------------------------------
+By Richard W.M. Jones <rich@annexia.org>
+
+What is DLIFE?
+--------------
+
+DLIFE is a distributed version of Tom S. Ray's Tierra artificial life
+program. Note that the machine language used is similar to but not
+compatible with Tierra. Tom Ray talks about his work (as far as I
+know, never completed) to create a ``Digital Reserve''. The DLIFE
+project is a development of this.
+
+In other words, it's an alternative to the tedious process of cracking
+RC5 keys or searching for aliens. You've got a supercomputer on your
+desk, let's go and create some life ...
+
+It consists of a highly optimized engine for running the artificial
+life cells in a virtual machine, written in C, and some Perl scripts
+which can upload and download cells from central ``cell-bank''
+servers.
+
--- /dev/null
+#ifndef DLIFE_CONFIG_H
+#define DLIFE_CONFIG_H
+@TOP@
+
+/*
+ * Defaults for configuration settings
+ */
+
+#undef PACKAGE
+#undef VERSION
+#undef SPOOLDIR
+#undef CONFDIR
+
+@BOTTOM@
+
+#endif /* DLIFE_CONFIG_H */
--- /dev/null
+dnl aclocal.m4 generated automatically by aclocal 1.4-p6
+
+dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
+# Do all the work for Automake. This macro actually does too much --
+# some checks are only needed if your package does certain things.
+# But this isn't really a big deal.
+
+# serial 1
+
+dnl Usage:
+dnl AM_INIT_AUTOMAKE(package,version, [no-define])
+
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])
+PACKAGE=[$1]
+AC_SUBST(PACKAGE)
+VERSION=[$2]
+AC_SUBST(VERSION)
+dnl test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+ifelse([$3],,
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
+AC_REQUIRE([AM_SANITY_CHECK])
+AC_REQUIRE([AC_ARG_PROGRAM])
+dnl FIXME This is truly gross.
+missing_dir=`cd $ac_aux_dir && pwd`
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}, $missing_dir)
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}, $missing_dir)
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
+AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AC_REQUIRE([AC_PROG_MAKE_SET])])
+
+# Copyright 2002 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.4"])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION so it can be traced.
+# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+ [AM_AUTOMAKE_VERSION([1.4-p6])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "[$]*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "[$]*" != "X $srcdir/configure conftestfile" \
+ && test "[$]*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "[$]2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+rm -f conftest*
+AC_MSG_RESULT(yes)])
+
+dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
+dnl The program must properly implement --version.
+AC_DEFUN([AM_MISSING_PROG],
+[AC_MSG_CHECKING(for working $2)
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if ($2 --version) < /dev/null > /dev/null 2>&1; then
+ $1=$2
+ AC_MSG_RESULT(found)
+else
+ $1="$3/missing $2"
+ AC_MSG_RESULT(missing)
+fi
+AC_SUBST($1)])
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file.
+
+AC_DEFUN([AM_CONFIG_HEADER],
+[AC_PREREQ([2.12])
+AC_CONFIG_HEADER([$1])
+dnl When config.status generates a header, we must update the stamp-h file.
+dnl This file resides in the same directory as the config header
+dnl that is generated. We must strip everything past the first ":",
+dnl and everything past the last "/".
+AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
+ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>,
+<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
+<<am_indx=1
+for am_file in <<$1>>; do
+ case " <<$>>CONFIG_HEADERS " in
+ *" <<$>>am_file "*<<)>>
+ echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx
+ ;;
+ esac
+ am_indx=`expr "<<$>>am_indx" + 1`
+done<<>>dnl>>)
+changequote([,]))])
+
+# Define a conditional.
+
+AC_DEFUN([AM_CONDITIONAL],
+[AC_SUBST($1_TRUE)
+AC_SUBST($1_FALSE)
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi])
+
--- /dev/null
+#FIG 3.2
+Landscape
+Center
+Inches
+Letter
+100.00
+Single
+-2
+1200 2
+6 2100 825 2775 2025
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 2100 825 2775 825 2775 2025 2100 2025 2100 825
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 2100 975 2550 975 2550 2025 2100 2025 2100 975
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 2550 1200 2775 1200 2775 1275 2550 1275 2550 1200
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 2550 1275 2775 1275 2775 1350 2550 1350 2550 1275
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 2550 1350 2775 1350 2775 1425 2550 1425 2550 1350
+-6
+6 5850 825 6525 2025
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 5850 825 6525 825 6525 2025 5850 2025 5850 825
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 5850 975 6300 975 6300 2025 5850 2025 5850 975
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 6300 1200 6525 1200 6525 1275 6300 1275 6300 1200
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 6300 1275 6525 1275 6525 1350 6300 1350 6300 1275
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 6300 1350 6525 1350 6525 1425 6300 1425 6300 1350
+-6
+6 675 5400 1650 6330
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 808 5400 1517 5400 1517 6020 808 6020 808 5400
+2 4 0 1 0 7 50 0 -1 0.000 0 0 4 0 0 5
+ 1473 5931 1473 5489 852 5489 852 5931 1473 5931
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 808 6109 1517 6109 1650 6330 675 6330 808 6109
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 853 6135 1337 6135 1428 6286 762 6286 853 6135
+-6
+6 1950 6450 2925 7380
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 2083 6450 2792 6450 2792 7070 2083 7070 2083 6450
+2 4 0 1 0 7 50 0 -1 0.000 0 0 4 0 0 5
+ 2748 6981 2748 6539 2127 6539 2127 6981 2748 6981
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 2083 7159 2792 7159 2925 7380 1950 7380 2083 7159
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 2128 7185 2612 7185 2703 7336 2037 7336 2128 7185
+-6
+6 3525 5775 4500 6705
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 3658 5775 4367 5775 4367 6395 3658 6395 3658 5775
+2 4 0 1 0 7 50 0 -1 0.000 0 0 4 0 0 5
+ 4323 6306 4323 5864 3702 5864 3702 6306 4323 6306
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 3658 6484 4367 6484 4500 6705 3525 6705 3658 6484
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 3703 6510 4187 6510 4278 6661 3612 6661 3703 6510
+-6
+6 3525 5175 4500 5456
+1 4 0 1 0 7 50 0 -1 0.000 1 0.0000 3666 5326 39 39 3633 5305 3698 5348
+1 4 0 1 0 7 50 0 -1 0.000 1 0.0000 3774 5326 39 39 3742 5305 3807 5348
+1 4 0 1 0 7 50 0 -1 0.000 1 0.0000 3882 5326 39 39 3850 5305 3915 5348
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 3525 5175 4500 5175 4500 5456 3525 5456 3525 5175
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 4110 5326 4153 5326 4153 5456 4110 5456 4110 5326
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 4197 5326 4240 5326 4240 5456 4197 5456 4197 5326
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 4283 5326 4327 5326 4327 5456 4283 5456 4283 5326
+-6
+6 5100 6075 6075 7005
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 5233 6075 5942 6075 5942 6695 5233 6695 5233 6075
+2 4 0 1 0 7 50 0 -1 0.000 0 0 4 0 0 5
+ 5898 6606 5898 6164 5277 6164 5277 6606 5898 6606
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 5233 6784 5942 6784 6075 7005 5100 7005 5233 6784
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 5278 6810 5762 6810 5853 6961 5187 6961 5278 6810
+-6
+6 900 4725 2100 5175
+4 0 0 50 0 0 12 0.0000 4 180 1170 900 4875 (runs from cron\001
+4 0 0 50 0 0 12 0.0000 4 180 870 900 5100 every hour)\001
+-6
+6 1875 5775 3075 6225
+4 0 0 50 0 0 12 0.0000 4 180 1170 1875 5925 (runs from cron\001
+4 0 0 50 0 0 12 0.0000 4 180 870 1875 6150 every hour)\001
+-6
+6 5025 5475 6225 5925
+4 0 0 50 0 0 12 0.0000 4 180 1170 5025 5625 (runs from cron\001
+4 0 0 50 0 0 12 0.0000 4 180 870 5025 5850 every hour)\001
+-6
+6 6825 4800 8025 5250
+4 0 0 50 0 0 12 0.0000 4 180 1170 6825 4950 (runs from cron\001
+4 0 0 50 0 0 12 0.0000 4 180 870 6825 5175 every hour)\001
+-6
+6 6975 5370 7950 6300
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 7108 5370 7817 5370 7817 5990 7108 5990 7108 5370
+2 4 0 1 0 7 50 0 -1 0.000 0 0 4 0 0 5
+ 7773 5901 7773 5459 7152 5459 7152 5901 7773 5901
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 7108 6079 7817 6079 7950 6300 6975 6300 7108 6079
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 7153 6105 7637 6105 7728 6256 7062 6256 7153 6105
+-6
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 1 2
+ 0 0 1.00 60.00 120.00
+ 0 0 1.00 60.00 120.00
+ 2475 5325 2475 2550
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 1 2
+ 0 0 1.00 60.00 120.00
+ 0 0 1.00 60.00 120.00
+ 3600 4200 2850 2475
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 1 2
+ 0 0 1.00 60.00 120.00
+ 0 0 1.00 60.00 120.00
+ 4425 4125 5700 2475
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 1 2
+ 0 0 1.00 60.00 120.00
+ 0 0 1.00 60.00 120.00
+ 5700 5100 6075 2550
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 1 2
+ 0 0 1.00 60.00 120.00
+ 0 0 1.00 60.00 120.00
+ 7275 4425 6450 2475
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 1 2
+ 0 0 1.00 60.00 120.00
+ 0 0 1.00 60.00 120.00
+ 1425 4275 2100 2475
+4 0 0 50 0 0 12 0.0000 4 180 1080 2025 2400 dlife_server.pl\001
+4 0 0 50 0 0 12 0.0000 4 180 1080 5625 2325 dlife_server.pl\001
+4 0 0 50 0 0 12 0.0000 4 180 1020 900 4500 dlife_client.pl\001
+4 0 0 50 0 0 12 0.0000 4 180 1020 2025 5625 dlife_client.pl\001
+4 0 0 50 0 0 12 0.0000 4 180 1020 3525 4425 dlife_client.pl\001
+4 0 0 50 0 0 12 0.0000 4 180 1020 5100 5325 dlife_client.pl\001
+4 0 0 50 0 0 12 0.0000 4 180 1020 6900 4650 dlife_client.pl\001
+4 0 0 50 0 0 12 0.0000 4 180 795 3375 4725 (runs from\001
+4 0 0 50 0 0 12 0.0000 4 180 1545 3375 4950 /etc/ppp/ip-up.local)\001
+4 0 0 50 0 0 12 0.0000 4 135 540 3675 5700 modem\001
+4 0 0 50 0 0 12 0.0000 4 180 780 675 6750 dlife_soup\001
+4 0 0 50 0 0 12 0.0000 4 180 780 2025 7650 dlife_soup\001
+4 0 0 50 0 0 12 0.0000 4 180 780 2025 7875 dlife_soup\001
+4 0 0 50 0 0 12 0.0000 4 180 780 3600 7050 dlife_soup\001
+4 0 0 50 0 0 12 0.0000 4 180 780 5250 7350 dlife_soup\001
+4 0 0 50 0 0 12 0.0000 4 180 780 7125 6675 dlife_soup\001
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+ <head>
+ <title>DLIFE distributed architecture reference</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+ <h1>DLIFE distributed architecture reference</h1>
+
+ <p>
+ DLIFE is distributed, meaning that many people
+ may allocate their spare computing cycles and
+ memory in order to form something which approximates
+ a very large single soup. Actually modelling a
+ very large soup, however, would be very difficult:
+ such a program would have a high communication
+ overhead, would be totally unsuitable to run on
+ the Internet, and adding nodes to this would bring
+ diminishing returns. Therefore DLIFE uses a simpler
+ model: individual computers run small soups, and
+ from time to time, soups exchange a few cells at
+ random with each other. In effect we form a series
+ of islands connected by archipelagoes.
+ </p>
+
+ <h2>Processes</h2>
+
+ <p>
+ There are currently three processes involved:
+ </p>
+
+ <ul>
+ <li> <b>dlife_soup</b>: This program runs continuously,
+ one on each client CPU, simulating a single soup.
+ It is written in C and designed to be as small and
+ fast as possible. This is the only part of DLIFE which
+ clients need to run all the time.
+ <li> <b>dlife_client.pl</b>: This is a Perl script which
+ runs infrequently (normally once per hour, but it
+ could be more or less often, or it could be run
+ on-demand when a PPP connection is brought up). The Perl script is
+ responsible for exchanging cells with the DLIFE server.
+ <li> <b>dlife_server.pl</b>: This is the DLIFE server
+ script. It only runs on servers (obviously). It acts
+ as a repository for cells being exchanged between
+ clients.
+ </ul>
+
+ <p>
+ The following diagram shows the interaction between these
+ three programs.
+ </p>
+
+ <img src="archproc.gif"
+ alt="[Diagram] Interaction between DLIFE processes"
+ width=491 height=475>
+
+ <p>
+ As shown, there are five client computers and two
+ servers. The second client computer has two CPUs,
+ and runs dlife_soup continuously on both. The
+ third client computer is connected to the Internet
+ by a modem, and so runs dlife_client.pl from
+ <tt>/etc/ppp/ip-up.local</tt> (this script runs whenever
+ the Internet connection is brought up). All the
+ other computers are permanently connected to the
+ Internet, and dlife_client.pl runs periodically
+ from <tt>cron</tt>. Clients may connect and exchange
+ cells with more than one server. In the diagram
+ above, the third client computer connects to
+ both servers.
+ </p>
+
+ <h2>Cells in files</h2>
+
+ <p>
+ The long-running dlife_soup program does not
+ contain any network code. All network communications
+ are handled by dlife_client.pl. Instead, dlife_soup
+ contains code to save and load cells to files.
+ </p>
+
+ <p>
+ dlife_soup saves (by default) six cells per hour,
+ at random, into the directory:
+ </p>
+
+ <p>
+ <tt>/var/spool/dlife/outgoing/</tt>
+ </p>
+
+ <p>
+ dlife_soup loads (by default) four cells per hour,
+ at random, from the directory:
+ </p>
+
+ <p>
+ <tt>/var/spool/dlife/incoming/</tt>
+ </p>
+
+ <p>
+ The dlife_client.pl program takes some cells at
+ random from the <tt>outgoing</tt> spool
+ directory and uploads them to one or more servers
+ (see the <a href="#conf">configuration section</a>
+ below). It then asks the server(s) to send some
+ cells, and it saves these in the <tt>incoming</tt>
+ spool directory.
+ </p>
+
+ <p>
+ The dlife_server.pl program listens for client
+ connections, and uploads or downloads cells. It
+ saves its cells in the directory:
+ </p>
+
+ <p>
+ <tt>/var/spool/dlife/store/</tt>
+ </p>
+
+ <h2>DLIFE network protocol</h2>
+
+ <p>
+ The DLIFE network protocol is a very simple
+ ASCII based protocol, similar to (but much
+ more limited than) FTP.
+ </p>
+
+ <p>
+ Servers listen for connections on port 5904.
+ When a client connects, they send back the following
+ identifying string:
+ </p>
+
+<pre>
+DLIFE SERVER <version> <protocol> <CR> <LF>
+</pre>
+
+ <p>
+ <tt><version></tt> is the server version, for
+ information only.
+ </p>
+
+ <p>
+ <tt><protocol></tt> is the protocol version. The
+ protocol described below is version 1.x (for some digit
+ ``x''). If a server reports a different major version
+ number (eg. 2.x) then this is an indication that the
+ protocol has changed dramatically and current clients
+ should give up and abort.
+ </p>
+
+ <p>
+ Clients connect to servers on port 5904 and
+ issue a series of simple four letter commands.
+ Each command should take the form:
+ </p>
+
+<pre>
+<command> [ <space> <arguments ...> ] <CR> <LF>
+</pre>
+
+ <p>
+ There are currently four commands: <tt>HELO</tt>,
+ <tt>STOR</tt>, <tt>RETR</tt> and <tt>QUIT</tt>.
+ </p>
+
+ <p>
+ Servers respond to commands with a three digit
+ response code and some optional human-readable text:
+ </p>
+
+<pre>
+XYZ [ <space> text ... ] <CR> <LF>
+</pre>
+
+ <p>
+ Of the response code, only the first digit (``<tt>X</tt>'')
+ is meaningful to clients. As for FTP, this digit can
+ have the following meanings:
+ </p>
+
+ <table border=1>
+ <tr>
+ <th> Response code </th> <th> Meaning </th>
+ </tr>
+ <tr>
+ <td> 1xx </td>
+ <td> Command OK. Ready to send data, <i>or</i> ready
+ to receive data.
+ </td>
+ </tr>
+ <tr>
+ <td> 2xx </td>
+ <td> Command OK. Ready for your next command.
+ </td>
+ </tr>
+ <tr>
+ <td> 4xx </td>
+ <td> Temporary error. The client can retry the last command
+ without modification and it may well succeed next time.
+ </td>
+ </tr>
+ <tr>
+ <td> 5xx </td>
+ <td> Error. The client should not just retry the same
+ command, but needs to reformulate the command or
+ cancel the operation and report an error back to the
+ user.
+ </td>
+ </tr>
+ </table>
+
+ <h3>The HELO command</h3>
+
+ <p>
+ The <tt>HELO</tt> command has the following form:
+ </p>
+
+<pre>
+HELO <space> <client_hostname>
+ <space> <client_version> <CR> <LF>
+</pre>
+
+ <p>
+ where <client_hostname> is the client
+ hostname (or the client may just send "-" character)
+ and <client_version> is the client version
+ number, used just for information only.
+ </p>
+
+ <p>
+ The server should always respond with 2xx to
+ this command.
+ </p>
+
+ <p>
+ A typical interaction:
+ </p>
+
+<pre>
+> HELO - 0.0.12
+< 200 Hello.
+</pre>
+
+ <h3>The STOR command</h3>
+
+ <p>
+ The <tt>STOR</tt> command is used to upload a single
+ cell to the server.
+ </p>
+
+ <p>
+ The format of the command is:
+ </p>
+
+<pre>
+STOR <CR> <LF>
+</pre>
+
+ <p>
+ If the server accepts the command and is ready to
+ upload a cell, it will reply with a 1xx response.
+ The client should then send the cell as a series
+ of hex nybbles, terminated by the sequence
+ <tt><CR> <LF> . <CR> <LF></tt>.
+ </p>
+
+ <p>
+ A typical interaction:
+ </p>
+
+<pre>
+> STOR
+< 100 Send me the cell, terminated by ".".
+> 00000000010901010100002227
+> 0000000100FFFFFFFFFFFFFFFF
+> : :
+> : :
+> 00010000002402020202020202022027
+> 0001010101
+> .
+< 200 Cell was uploaded OK.
+</pre>
+
+ <p>
+ Servers will typically have limitations on the
+ number and type of cells that they will accept.
+ Generally they will only accept a small number
+ of uploads per session, and each cell will be
+ limited to 8192 bytes or less.
+ </p>
+
+ <h3>The RETR command</h3>
+
+ <p>
+ The <tt>RETR</tt> command is used to download
+ a cell from the cell bank. The format of the command
+ is:
+ </p>
+
+<pre>
+RETR <CR> <LF>
+</pre>
+
+ <p>
+ If the server is ready to serve a cell, it will
+ reply with a 1xx response, followed by a series
+ of hex nybbles and terminated by the
+ sequence
+ <tt><CR> <LF> . <CR> <LF></tt>
+ and immediately followed by a 2xx response.
+ </p>
+
+ <p>
+ A typical interaction:
+ </p>
+
+<pre>
+> RETR
+< 100 OK. Sending you a cell.
+< 00000000010901010100002227
+< 0000000100FFFFFFFFFFFFFFFF
+< : :
+< : :
+< 00010000002402020202020202022027
+< 0001010101
+< .
+< 200 Cell was sent OK.
+</pre>
+
+ <h3>The QUIT command</h3>
+
+ <p>
+ The <tt>QUIT</tt> command terminates a session
+ (clients may also just close a session).
+ </p>
+
+ <p>
+ The format of the command is:
+ </p>
+
+<pre>
+QUIT <CR> <LF>
+</pre>
+
+ <p>
+ The server responds with a 2xx message and then
+ closes its end of the connection.
+ </p>
+
+ <p>
+ A typical interaction:
+ </p>
+
+<pre>
+> QUIT
+< 200 Goodbye.
+<i>(socket is closed)</i>
+</pre>
+
+ <a name="conf"><h2>Configuration files</h2></a>
+
+ <h3>/etc/dlife/client.conf</h3>
+
+ <p>
+ This file is used to configure the network client.
+ The file tells the client which server or servers
+ to connect to.
+ </p>
+
+ <p>
+ The client can be configured to:
+ </p>
+
+ <ul>
+ <li> Download a list of servers from a web page.
+ <li> Contact only servers in the current ``zone'' (eg.
+ only servers in the UK or Europe). And/or:
+ <li> Contact servers directly by name.
+ </ul>
+
+ <h4>server_url command</h4>
+
+ <p>
+ The <tt>server_url</tt> command may be optionally
+ given. It directs the client to download the web
+ page given in the URL. The web page should contain
+ a master list of servers.
+ </p>
+
+<pre>
+server_url <a href="http://dlife.annexia.org/servers.txt">http://dlife.annexia.org/servers.txt</a>
+</pre>
+
+ <h4>server_zone command</h4>
+
+ <p>
+ The <tt>server_zone</tt> command is optional. It
+ should be used in conjunction with the
+ <tt>server_url</tt> command. It
+ directs the client to only consider servers
+ in the particular zone or zones listed.
+ </p>
+
+ <p>
+ The general form is:
+ </p>
+
+<pre>
+server_zone <zone> [<zone> [...]]
+</pre>
+
+ <p>
+ Each <tt><zone></tt> argument should have the
+ form:
+ </p>
+
+ <ul>
+ <li> An ISO3166 country code, eg. <tt>uk</tt>, <tt>us</tt>. Or:
+ <li> A geographical continent, eg. <tt>eu</tt>. Or:
+ <li> A domain name, preceeded by a dot ("."),
+ eg. <tt>.bibliotech.net</tt>.
+ </ul>
+
+ <h4>server command</h4>
+
+ <p>
+ The <tt>server</tt> command directs the client to
+ connect directly the server or servers listed.
+ </p>
+
+<pre>
+server dlife1.bibliotech.co.uk dlife2.bibliotech.co.uk
+</pre>
+
+ <h4>max_cells_upload_per_pass command</h4>
+
+ <p>
+ The <tt>max_cells_upload_per_pass</tt> directs
+ the client to attempt to upload this many cells
+ in a pass. Note that the server probably imposes
+ its own limit.
+ </p>
+
+ <h4>max_cells_download_per_pass command</h4>
+
+ <p>
+ The <tt>max_cells_download_per_pass</tt> directs
+ the client to attempt to download this many cells
+ in a pass. Note that the server probably imposes
+ its own limit. It is a good idea to ensure that
+ <tt>max_cells_upload_per_pass</tt> >
+ <tt>max_cells_download_per_pass</tt>.
+ </p>
+
+ <h3>/etc/dlife/soup.conf</h3>
+
+ <p>
+ The <tt>soup.conf</tt> file configures various
+ internal aspects of the DLIFE virtual machine.
+ For full documentation, please see the example
+ file provided with the source distribution.
+ </p>
+
+ <h2>Typical configurations</h2>
+
+ <h3>Default configuration</h3>
+
+
+
+
+
+
+ <!-- default,
+ modem,
+ behind firewall
+ -->
+
+
+
+ <hr>
+ <address><a href="mailto:rich@annexia.org">Richard Jones</a></address>
+<!-- Created: Sat Oct 7 10:12:59 BST 2000 -->
+<!-- hhmts start -->
+Last modified: Wed Oct 11 23:19:19 BST 2000
+<!-- hhmts end -->
+ </body>
+</html>
--- /dev/null
+/* DLIFE Copyright (C) 2000 Richard W.M. Jones <rich@annexia.org>
+ * and other authors listed in the ``AUTHORS'' file.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id: cell.c,v 1.3 2002/12/11 17:16:21 rich Exp $
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#ifdef HAVE_ASSERT_H
+#include <assert.h>
+#endif
+
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+
+#ifdef HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
+
+#include "cell.h"
+#include "soup.h"
+#include "random.h"
+#include "params.h"
+#include "dlink.h"
+#include "image.h"
+#include "load.h"
+
+#define PRINT_SIMULATION_STATS 0
+
+static volatile int quit = 0, save = 0, outgoing = 0, incoming = 0, info = 0;
+static void save_cell_in_outgoing (struct state *, const struct cell *);
+
+/* Initialize the common fields of a cell. */
+static inline void
+init_cell (struct cell *cell)
+{
+ /* Public fields are subject to initialization errors. */
+ if (! chance (cell_initialization_failure))
+ {
+ cell->a = cell->b = cell->i = cell->p = 0;
+ memset (cell->stack, 0, sizeof cell->stack);
+ }
+ else
+ {
+ int i;
+
+ cell->a = get_rand_short ();
+ cell->b = get_rand_short ();
+ cell->i = get_rand_short ();
+ cell->p = 0; /* Cell would be non-viable otherwise. */
+
+ for (i = 0; i < STACK_SIZE; ++i)
+ cell->stack[i] = get_rand_short ();
+ }
+ cell->next = cell->prev = 0;
+ cell->worse = cell->better = 0;
+ cell->sp = 0;
+ cell->errors = 0;
+ cell->state = state_exec;
+ cell->dir = 0;
+ cell->plen = 0;
+ cell->lim = 0;
+ cell->frag = 0;
+ cell->daughter = 0;
+ cell->cycle = 0;
+ cell->crc = 0; /* Initialize these at DIVIDE. */
+ cell->mother_crc = 0;
+}
+
+struct cell *
+cell_malloc (struct state *state,
+ const struct cell *mother,
+ struct soup_frag *daughter_frag)
+{
+ struct cell *cell;
+
+ cell = malloc (sizeof (struct cell));
+ if (cell == 0) { perror ("malloc"); abort (); }
+
+ init_cell (cell);
+ cell->frag = daughter_frag;
+
+ state->nr_cells_allocated++;
+
+ return cell;
+}
+
+void
+cell_divide (struct state *state,
+ const struct cell *mother,
+ struct cell *daughter)
+{
+ /* Initialize CRC fields. */
+ daughter->mother_crc = mother->crc;
+ daughter->crc = soup_frag_compute_crc32 (state, daughter->frag);
+
+ /* If the outgoing signal has just gone, then this cell is the
+ * lucky cell which has been nominated to be written into the
+ * outgoing queue.
+ */
+ if (outgoing)
+ {
+ outgoing = 0;
+ save_cell_in_outgoing (state, daughter);
+ }
+
+#if 0
+ printf ("DIVIDE: 0x%08X/%d -> 0x%08X/%d\n",
+ daughter->mother_crc, mother->frag->len,
+ daughter->crc, daughter->frag->len);
+#endif
+}
+
+/* Put a cell onto the alive list. */
+void
+cell_activate (struct state *state, struct cell *cell)
+{
+ insert_before_first (cell, &state->alive_list);
+
+ /* We assume that cells start off with no errors. */
+ assert (cell->errors == 0);
+ insert_before_first (cell, &state->best_list);
+
+ state->nr_cells_alive++;
+}
+
+/* This function is called after the INC_ERRORS macro has incremented
+ * the number of errors in a cell and found that the cell should be
+ * moved up in the linked list by one or more places.
+ */
+void
+_cell_move_worse (struct state *state, struct cell *cell)
+{
+ while (cell->worse && cell->errors > cell->worse->errors)
+ move_towards_last (cell, &state->best_list);
+}
+
+/* Kill a cell (and undivided offspring, if any). */
+void
+cell_kill (struct state *state, struct cell *cell)
+{
+ remove_element (cell, &state->alive_list);
+ remove_element (cell, &state->best_list);
+
+ soup_frag_free (state, cell->frag);
+
+ /* Pro-life programmers may wish to look away at this point ... */
+ if (cell->daughter)
+ {
+ soup_frag_free (state, cell->daughter->frag);
+ cell->daughter->errors = -1;
+ free (cell->daughter);
+
+ state->nr_cells_allocated--;
+ }
+
+ cell->errors = -1;
+ free (cell);
+
+ state->nr_cells_allocated--;
+ state->nr_cells_alive--;
+}
+
+/* Run the grim reaper, culling cells until the amount of free soup
+ * left is less than the appropriate threshold.
+ */
+static inline void
+reaper (struct state *state)
+{
+ int bytes_to_free;
+
+ /* How many bytes do we need to free up? */
+ bytes_to_free = (100 - reaper_reap_threshold) * state->soup_size
+ / 100 - state->soup_free;
+ assert (bytes_to_free > 0);
+
+#if 0
+ printf ("\ninvoking reaper to save %d bytes of soup ...\n", bytes_to_free);
+#endif
+
+ while (bytes_to_free > 0)
+ {
+ struct cell *cell;
+
+ /* Pick the most error-prone cell and kill it. */
+ cell = (struct cell *) state->best_list.last;
+ bytes_to_free -= cell->frag->len;
+ if (cell->daughter) bytes_to_free -= cell->daughter->frag->len;
+
+#if 0
+ printf (" killing cell with %d errors\n", cell->errors);
+#endif
+
+ cell_kill (state, cell);
+ }
+}
+
+/* Remove any cells with more than MAX_ERRORS errors. */
+static inline void
+reap_error_prone_cells (struct state *state)
+{
+ struct cell *cell;
+
+ /* Just go down the list of cells, killing them until we
+ * reach a cell with < MAX_ERRORS errors.
+ */
+ while ((cell = (struct cell *) state->best_list.last) &&
+ cell->errors >= MAX_ERRORS)
+ {
+#if 0
+ printf ("killing cell with %d errors (>= MAX_ERRORS)\n", cell->errors);
+#endif
+
+ cell_kill (state, cell);
+ }
+}
+
+static void
+check_one_cell (struct state *state, const struct cell *cell, int is_daughter)
+{
+ assert (cell->sp >= 0 && cell->sp < STACK_SIZE);
+ assert (cell->errors >= 0);
+ assert (cell->state == state_exec || cell->state == state_find);
+ assert (cell->dir >= -1 && cell->dir <= 1);
+ assert (cell->frag != 0);
+
+ if (cell->daughter)
+ {
+ assert (is_daughter == 0);
+ check_one_cell (state, cell->daughter, 1);
+ }
+}
+
+/* Check the consistency of each cell. This is only used when we are
+ * debugging the simulation.
+ */
+void
+cell_check (struct state *state)
+{
+ const struct cell *p;
+ int alive = 0, allocated = 0, errors = 0;
+
+ /* Check the alive list and each cell on it. */
+ for (p = (struct cell *) state->alive_list.first; p; p = p->next)
+ {
+ check_one_cell (state, p, 0);
+ alive++; allocated++;
+ if (p->daughter) allocated++;
+ }
+
+ assert (alive == state->nr_cells_alive);
+ assert (allocated == state->nr_cells_allocated);
+
+ /* Check the best list. */
+ alive = allocated = 0;
+ for (p = (struct cell *) state->best_list.first; p; p = p->worse)
+ {
+ assert (errors <= p->errors);
+ errors = p->errors;
+ alive++; allocated++;
+ if (p->daughter) allocated++;
+ }
+
+ assert (alive == state->nr_cells_alive);
+ assert (allocated == state->nr_cells_allocated);
+}
+
+/* Take a complete checkpoint of the state and save it onto disk. */
+static void
+save_me (struct state *state)
+{
+ char filename2[256], filename3[256];
+
+ sprintf (filename2, "%s.new", state->filename);
+
+ if (image_save (state, filename2) == 0)
+ {
+ sprintf (filename3, "%s~", state->filename);
+
+ rename (state->filename, filename3);
+ rename (filename2, state->filename);
+
+ if (verbose)
+ printf ("CPU %d: Saved soup image to file.\n", state->thread_num);
+ }
+ else
+ {
+ sprintf (filename3, "/tmp/%s", state->filename);
+
+ if (image_save (state, filename3) == 0)
+ {
+ fprintf (stderr,
+ "save directory is unwritable! saved to %s instead\n",
+ filename3);
+ }
+ else
+ {
+ fprintf (stderr, "could not save state!\n");
+ }
+ }
+}
+
+/* Check the incoming queue. */
+static void
+check_incoming (struct state *state)
+{
+ DIR *dir;
+ struct dirent *d;
+ char filename[256];
+ int cells_read = 0;
+
+#ifndef HAVE_OPENDIR
+#error "require working opendir/readdir/closedir"
+#endif
+
+ dir = opendir ("incoming");
+ if (dir == NULL) { perror ("incoming"); return; }
+
+ while ((d = readdir (dir)) != 0)
+ {
+ int len = strlen (d->d_name);
+
+ if (len >= 4 &&
+ d->d_name[len-4] == '.' &&
+ d->d_name[len-3] == 'd' &&
+ d->d_name[len-2] == 'l' &&
+ d->d_name[len-1] == 'o')
+ {
+ if (cells_read < max_cells_incoming_per_pass)
+ {
+ struct cell *cell;
+
+ sprintf (filename, "incoming/%s", d->d_name);
+
+ /* Read the contents of the file. */
+ cell = load_cell (state, filename);
+
+ if (cell)
+ {
+ cell_activate (state, cell);
+ cells_read++;
+ }
+ }
+
+ /* Remove the file - we've finished with it now. */
+ unlink (filename);
+ }
+ }
+}
+
+static void
+info_to_syslog (const struct state *state)
+{
+ int soup_used_percent
+ = 100 * (state->soup_size - state->soup_free) / state->soup_size;
+
+#ifdef HAVE_SYSLOG
+ syslog (LOG_INFO,
+ "#%d: cycles: %LuB cells: %d [+%d] soup: %d%% (%d/%d)",
+ state->thread_num,
+ state->cell_cycle / 1000000000,
+ state->nr_cells_alive,
+ state->nr_cells_allocated - state->nr_cells_alive,
+ soup_used_percent,
+ state->soup_size - state->soup_free,
+ state->soup_size);
+#endif
+}
+
+static void
+catch_quit (int sig)
+{
+ quit = 1;
+}
+
+static void
+catch_alarm (int sig)
+{
+ static int minutes = 0;
+
+ minutes++;
+
+ if ((minutes % save_period) == 0)
+ {
+ save = 1;
+ }
+
+ if ((minutes % outgoing_period) == 0)
+ {
+ outgoing = 1;
+ }
+
+ if ((minutes % incoming_period) == 0)
+ {
+ incoming = 1;
+ }
+
+ if ((minutes % info_period) == 0)
+ {
+ info = 1;
+ }
+
+ alarm (60);
+}
+
+void
+run_thread (struct state *state)
+{
+ int start_time = time (NULL), end_time;
+ unsigned long long start_cycle = state->cell_cycle;
+ struct sigaction sigact;
+
+ /* Set up signal handlers to save the soup periodically and
+ * handle exits gracefully.
+ */
+ memset (&sigact, 0, sizeof sigact);
+ sigact.sa_handler = catch_quit;
+ sigact.sa_flags = 0;
+
+ sigaction (SIGINT, &sigact, 0);
+ sigaction (SIGQUIT, &sigact, 0);
+ sigaction (SIGTERM, &sigact, 0);
+
+ sigact.sa_handler = catch_alarm;
+ sigact.sa_flags = SA_RESTART;
+ sigaction (SIGALRM, &sigact, 0);
+
+ alarm (60);
+
+ while (!quit)
+ {
+ struct cell *p;
+ int soup_used_percent;
+
+ /* Iterate over the list of alive cells, executing a single
+ * intruction of each.
+ */
+ for (p = (struct cell *) state->alive_list.first; p; p = p->next)
+ {
+ exec_insn (state, p);
+ }
+
+ /* Print some statistics. */
+ soup_used_percent
+ = 100 * (state->soup_size - state->soup_free) / state->soup_size;
+
+#if PRINT_SIMULATION_STATS
+ printf ("cycles: %LuB cells: %d [+%d] soup: %d%% \r",
+ state->cell_cycle / 1000000000,
+ state->nr_cells_alive,
+ state->nr_cells_allocated - state->nr_cells_alive,
+ soup_used_percent);
+ fflush (stdout);
+#endif
+
+ /* Do we need to invoke the grim reaper? */
+ if (soup_used_percent >= reaper_invoke_threshold)
+ {
+ reaper (state);
+ }
+
+ /* Do we need to reap any remaining cells with more than
+ * MAX_ERRORS errors?
+ */
+ reap_error_prone_cells (state);
+
+#if CHECK
+ soup_check (state);
+ cell_check (state);
+#endif
+
+ /* Save image every so often. */
+ if (save)
+ {
+ save = 0;
+ save_me (state);
+ }
+
+ /* Check incoming queue? */
+ if (incoming)
+ {
+ incoming = 0;
+ check_incoming (state);
+ }
+
+ /* Dump status information to syslog? */
+ if (info)
+ {
+ info = 0;
+ info_to_syslog (state);
+ }
+ }
+
+ end_time = time (NULL);
+
+ syslog (LOG_INFO, "CPU %d: Cycles processed: %LuB Time: %dH Cycles/second: %d\n",
+ state->thread_num,
+ (state->cell_cycle - start_cycle) / 1000000000,
+ (end_time - start_time) / (60 * 60),
+ (int) ((state->cell_cycle - start_cycle)
+ / (end_time - start_time)));
+
+ /* Each thread is responsible for saving its own state. */
+ save_me (state);
+}
+
+/* Something of a hack: get any fragment and return it. */
+struct soup_frag *
+_cell_get_any_frag (struct state *state)
+{
+ return ((struct cell *) state->alive_list.first)->frag;
+}
+
+/* Save the current state of the cell table to a file. This function
+ * is non-destructive.
+ */
+void
+cell_state_save (struct state *state, FILE *fp)
+{
+ struct cell *p;
+
+ /* Write out the number of cells. */
+ fwrite (&state->nr_cells_allocated, sizeof state->nr_cells_allocated, 1, fp);
+ fwrite (&state->nr_cells_alive, sizeof state->nr_cells_alive, 1, fp);
+
+ /* Write the cells out in order to the file. */
+ for (p = (struct cell *) state->alive_list.first; p; p = p->next)
+ {
+ p->fbase = p->frag->base;
+ fwrite (p, sizeof (struct cell), 1, fp);
+ if (p->daughter)
+ {
+ p->daughter->fbase = p->daughter->frag->base;
+ fwrite (p->daughter, sizeof (struct cell), 1, fp);
+ }
+ }
+}
+
+static int
+compare_nr_errors (const void *cv1, const void *cv2)
+{
+ const struct cell **cp1 = (const struct cell **) cv1;
+ const struct cell **cp2 = (const struct cell **) cv2;
+
+ return (*cp1)->errors - (*cp2)->errors;
+}
+
+/* Load the cells from a previously saved file. */
+void
+cell_state_load (struct state *state, FILE *fp)
+{
+ int i;
+ struct cell *p;
+ struct cell **cellptr_list;
+
+ assert (state->nr_cells_allocated == 0);
+ assert (state->nr_cells_alive == 0);
+
+ /* Read in the number of cells. */
+ if (fread (&state->nr_cells_allocated,
+ sizeof state->nr_cells_allocated, 1, fp) != 1)
+ {
+ syslog (LOG_ERR, "error in cell state\n");
+ abort ();
+ }
+ if (fread (&state->nr_cells_alive,
+ sizeof state->nr_cells_alive, 1, fp) != 1)
+ {
+ syslog (LOG_ERR, "error in cell state\n");
+ abort ();
+ }
+
+ assert (state->nr_cells_alive <= state->nr_cells_allocated);
+
+ cellptr_list = malloc (sizeof (struct cell *) * state->nr_cells_alive);
+
+ /* Read each cell in from the file. */
+ for (i = 0; i < state->nr_cells_alive; ++i)
+ {
+ p = malloc (sizeof (struct cell));
+ if (p == 0) { perror ("malloc"); abort (); }
+
+ if (fread (p, sizeof (struct cell), 1, fp) != 1)
+ {
+ syslog (LOG_ERR, "error in cell state\n");
+ abort ();
+ }
+
+ cellptr_list[i] = p;
+
+ insert_before_last (p, &state->alive_list);
+
+ if (p->daughter)
+ {
+ p->daughter = malloc (sizeof (struct cell));
+ if (p->daughter == 0) { perror ("malloc"); abort (); }
+
+ if (fread (p->daughter, sizeof (struct cell), 1, fp) != 1)
+ {
+ syslog (LOG_ERR, "error in cell state\n");
+ abort ();
+ }
+ }
+ }
+
+ /* Order the living cells from best to worst, and from this
+ * reconstruct the best list.
+ */
+ qsort (cellptr_list, state->nr_cells_alive, sizeof (struct cell *),
+ compare_nr_errors);
+
+ for (i = 0; i < state->nr_cells_alive; ++i)
+ {
+ insert_before_last (cellptr_list[i], &state->best_list);
+ }
+}
+
+/* This function is used when loading the soup (just after loading the
+ * cells) to fix up references from the cells to soup fragments. It
+ * uses the hidden ``fbase'' member of struct cell to save the reference.
+ */
+void
+_cell_fixup_soup_ref (struct state *state,
+ addr_t fbase, struct soup_frag *frag)
+{
+ struct cell *p;
+
+ for (p = (struct cell *) state->alive_list.first; p; p = p->next)
+ {
+ if (p->fbase == fbase)
+ {
+ p->frag = frag;
+ return;
+ }
+ else if (p->daughter && p->daughter->fbase == fbase)
+ {
+ p->daughter->frag = frag;
+ return;
+ }
+ }
+
+ syslog (LOG_ERR, "cell fixup not found (fbase = %d)\n", fbase);
+ abort ();
+}
+
+/* Save a single cell in the outgoing queue. */
+static void
+save_cell_in_outgoing (struct state *state,
+ const struct cell *cell)
+{
+ char filename[256];
+ FILE *fp;
+ int i;
+
+ /* Choose a random name. */
+ sprintf (filename, "outgoing/%d.dlo", get_rand_int());
+
+ fp = fopen (filename, "w");
+ if (fp == NULL) { perror (filename); return; } /* Fail silently. */
+
+ for (i = 0; i < cell->frag->len; ++i)
+ fprintf (fp, "%02X", get_soup (state, cell->frag, i));
+
+ fclose (fp);
+}
--- /dev/null
+/* DLIFE Copyright (C) 2000 Richard W.M. Jones <rich@annexia.org>
+ * and other authors listed in the ``AUTHORS'' file.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id: cell.h,v 1.1 2002/04/05 14:40:25 rich Exp $
+ */
+
+#ifndef cell_h
+#define cell_h
+
+#include "config.h"
+
+#include <stdio.h>
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h> /* For MAXHOSTNAMELEN. */
+#endif
+
+#include "types.h"
+#include "dlink.h"
+#include "state.h"
+#include "crc.h"
+
+struct soup_frag;
+
+#define STACK_SIZE 16
+
+/* These two parameters define the maximum cell size. The first parameter
+ * is the maximum length of searches permitted by the FINDB/FINDF
+ * commands. It stops those commands from running wild if a label is
+ * missing. The second one limits the maximum cell size that may be
+ * allocated by MALLOC - and hence directly the maximum cell size
+ * overall. There is also a minimum cell size, although we keep this
+ * small.
+ */
+#define FIND_LENGTH_LIMIT 512
+#define MAX_CELL_SIZE 512
+#define MIN_CELL_SIZE 10
+
+/* The maximum number of errors that a cell may get before we
+ * automatically blow it away (even if the soup isn't full and
+ * doesn't need reaping). This prevents us wasting valuable CPU
+ * time on cells which have gone completely AWOL.
+ */
+#define MAX_ERRORS 100
+
+enum cell_state
+{
+ state_exec,
+ state_find
+};
+
+struct cell
+{
+ struct cell *next; /* Alive cells are linked thru this list. */
+ struct cell *prev; /* Alive cells are linked thru this list. */
+ struct cell *worse; /* Cells are kept in error order on this list*/
+ struct cell *better; /* Cells are kept in error order on this list*/
+ reg_t a, b, i, p; /* Registers. */
+ reg_t stack[STACK_SIZE]; /* Stack. */
+ int sp; /* Stack pointer. */
+ int errors; /* Cumulative number of errors encountered */
+ enum cell_state state; /* Executing or finding. */
+ int dir; /* [Find] -1 = back, 1 = forwards */
+ int plen; /* [Find] length of pattern */
+ int lim; /* [Find] search limit (counts down to 0) */
+ struct soup_frag *frag; /* Fragment in the soup */
+ struct cell *daughter; /* Daughter (after MALLOC, before DIVIDE) */
+ unsigned long long cycle; /* Number of cycles of runtime. */
+ crc_t crc; /* CRC at birth (after mother's DIVIDE). */
+ crc_t mother_crc; /* CRC of mother. */
+ addr_t fbase; /* Used when saving/loading soup image only. */
+};
+
+extern int verbose;
+
+extern struct cell *cell_malloc (struct state *state,
+ const struct cell *mother,
+ struct soup_frag *daughter_frag);
+extern void cell_divide (struct state *state,
+ const struct cell *mother,
+ struct cell *daughter);
+extern void cell_activate (struct state *state,
+ struct cell *cell);
+extern void cell_kill (struct state *state,
+ struct cell *cell);
+
+extern void cell_state_load (struct state *state, FILE *fp);
+extern void cell_state_save (struct state *state, FILE *fp);
+
+extern void cell_check (struct state *state);
+
+extern void exec_insn (struct state *state, struct cell *cell);
+
+extern void run_thread (struct state *state);
+
+/* This macro is used to increment the error count in a cell. It
+ * ensures that the cell ``worst-to-best'' list is kept up to date.
+ */
+#define INC_ERRORS(state,cell) do { (cell)->errors++; if ((cell)->worse && (cell)->errors > (cell)->worse->errors) _cell_move_worse ((state), (cell)); } while (0)
+
+extern void _cell_move_worse (struct state *state, struct cell *cell);
+
+extern struct soup_frag *_cell_get_any_frag (struct state *state);
+
+extern void _cell_fixup_soup_ref (struct state *state,
+ addr_t fbase, struct soup_frag *frag);
+
+#endif /* cell_h */
--- /dev/null
+# DLIFE network client configuration file.
+
+# Note: You should either set ``server_url'' or set ``server''
+# (possibly both).
+
+#----------------------------------------------------------------------
+# If set, then the client will download the given web page looking
+# for servers to connect to.
+
+server_url http://dlife.annexia.org/servers.txt
+
+# If you want the client to only connect to servers in a given
+# geographical zone (in order to reduce network traffic), then
+# set this to a list of ISO 3166 country codes and/or geographical
+# continent codes and/or domain names.
+#
+# Example (1): The client will only connect to servers in the
+# United Kingdom, France and the Netherlands.
+#
+# server_zone uk fr nl
+#
+# Example (2): The client will only connect to servers in the
+# US or European Union.
+#
+# server_zone us eu
+#
+# Example (3): The client will only connect to servers in the
+# domain bibliotech.net.
+#
+# server_zone .bibliotech.net
+
+#----------------------------------------------------------------------
+# This causes the client to connect directly to the servers listed.
+#
+# Example: Connect to dlife1.bibliotech.net or dlife2.bibliotech.net.
+#
+# server dlife1.bibliotech.net dlife2.bibliotech.net
+
+#----------------------------------------------------------------------
+# How many cells to upload each pass (normally each hour).
+#
+max_cells_upload_per_pass 6
+
+# How many cells to download each pass (normally each hour).
+#
+max_cells_download_per_pass 4
--- /dev/null
+/* config.h.in. Generated automatically from configure.in by autoheader 2.13. */
+#ifndef DLIFE_CONFIG_H
+#define DLIFE_CONFIG_H
+
+#undef PACKAGE
+#undef VERSION
+#undef SPOOLDIR
+#undef CONFDIR
+
+/* Define if you have the closedir function. */
+#undef HAVE_CLOSEDIR
+
+/* Define if you have the getpwnam function. */
+#undef HAVE_GETPWNAM
+
+/* Define if you have the getuid function. */
+#undef HAVE_GETUID
+
+/* Define if you have the initgroups function. */
+#undef HAVE_INITGROUPS
+
+/* Define if you have the nice function. */
+#undef HAVE_NICE
+
+/* Define if you have the opendir function. */
+#undef HAVE_OPENDIR
+
+/* Define if you have the openlog function. */
+#undef HAVE_OPENLOG
+
+/* Define if you have the readdir function. */
+#undef HAVE_READDIR
+
+/* Define if you have the setgid function. */
+#undef HAVE_SETGID
+
+/* Define if you have the setuid function. */
+#undef HAVE_SETUID
+
+/* Define if you have the syslog function. */
+#undef HAVE_SYSLOG
+
+/* Define if you have the <assert.h> header file. */
+#undef HAVE_ASSERT_H
+
+/* Define if you have the <dirent.h> header file. */
+#undef HAVE_DIRENT_H
+
+/* Define if you have the <errno.h> header file. */
+#undef HAVE_ERRNO_H
+
+/* Define if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define if you have the <grp.h> header file. */
+#undef HAVE_GRP_H
+
+/* Define if you have the <pwd.h> header file. */
+#undef HAVE_PWD_H
+
+/* Define if you have the <signal.h> header file. */
+#undef HAVE_SIGNAL_H
+
+/* Define if you have the <stddef.h> header file. */
+#undef HAVE_STDDEF_H
+
+/* Define if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define if you have the <syslog.h> header file. */
+#undef HAVE_SYSLOG_H
+
+/* Define if you have the <time.h> header file. */
+#undef HAVE_TIME_H
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Name of package */
+#undef PACKAGE
+
+/* Version number of package */
+#undef VERSION
+
+
+#endif /* DLIFE_CONFIG_H */
--- /dev/null
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+configure:577: checking for a BSD compatible install
+configure:630: checking whether build environment is sane
+configure:687: checking whether make sets ${MAKE}
+configure:733: checking for working aclocal-1.4
+configure:746: checking for working autoconf
+configure:759: checking for working automake-1.4
+configure:772: checking for working autoheader
+configure:785: checking for working makeinfo
+configure:805: checking for gcc
+configure:918: checking whether the C compiler (gcc ) works
+configure:934: gcc -o conftest conftest.c 1>&5
+configure:960: checking whether the C compiler (gcc ) is a cross-compiler
+configure:965: checking whether we are using GNU C
+configure:974: gcc -E conftest.c
+configure:993: checking whether gcc accepts -g
+configure:1036: checking for a BSD compatible install
+configure:1089: checking whether make sets ${MAKE}
--- /dev/null
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --enable-check Enable extra internal consistency checks (slow)"
+ac_help="$ac_help
+ --enable-profile Enable code profiling"
+ac_help="$ac_help
+ --disable-user-check Do not check for existance of dlife account"
+ac_help="$ac_help
+ --enable-cron[=layout] Install cron script to run dlife net client
+ 'layout' may be 'auto' (default), 'standard',
+ or a path to crontab directory starting with /
+ --disable-cron Do not install cron script"
+ac_help="$ac_help
+ --enable-rc[=layout] Install rc script (runs dlife_soup at boot)
+ 'layout' may be 'auto' (default), 'standard',
+ or a path to local rc directory starting with /
+ --disable-rc Do not install rc script"
+ac_help="$ac_help
+ --with-spool=DIR Spool directory (default typically /var/spool/dlife)"
+ac_help="$ac_help
+ --with-conf=DIR Config directory (default typically /etc/dlife)"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=cell.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+am__api_version="1.4"
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:577: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
+echo "configure:630: checking whether build environment is sane" >&5
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "$*" != "X $srcdir/configure conftestfile" \
+ && test "$*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ { echo "configure: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" 1>&2; exit 1; }
+ fi
+
+ test "$2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ { echo "configure: error: newly created file is older than distributed files!
+Check your system clock" 1>&2; exit 1; }
+fi
+rm -f conftest*
+echo "$ac_t""yes" 1>&6
+if test "$program_transform_name" = s,x,x,; then
+ program_transform_name=
+else
+ # Double any \ or $. echo might interpret backslashes.
+ cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:687: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+PACKAGE=dlife
+
+VERSION=1.0.0
+
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
+fi
+cat >> confdefs.h <<EOF
+#define PACKAGE "$PACKAGE"
+EOF
+
+cat >> confdefs.h <<EOF
+#define VERSION "$VERSION"
+EOF
+
+
+
+missing_dir=`cd $ac_aux_dir && pwd`
+echo $ac_n "checking for working aclocal-${am__api_version}""... $ac_c" 1>&6
+echo "configure:733: checking for working aclocal-${am__api_version}" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (aclocal-${am__api_version} --version) < /dev/null > /dev/null 2>&1; then
+ ACLOCAL=aclocal-${am__api_version}
+ echo "$ac_t""found" 1>&6
+else
+ ACLOCAL="$missing_dir/missing aclocal-${am__api_version}"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
+echo "configure:746: checking for working autoconf" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoconf --version) < /dev/null > /dev/null 2>&1; then
+ AUTOCONF=autoconf
+ echo "$ac_t""found" 1>&6
+else
+ AUTOCONF="$missing_dir/missing autoconf"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working automake-${am__api_version}""... $ac_c" 1>&6
+echo "configure:759: checking for working automake-${am__api_version}" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (automake-${am__api_version} --version) < /dev/null > /dev/null 2>&1; then
+ AUTOMAKE=automake-${am__api_version}
+ echo "$ac_t""found" 1>&6
+else
+ AUTOMAKE="$missing_dir/missing automake-${am__api_version}"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
+echo "configure:772: checking for working autoheader" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoheader --version) < /dev/null > /dev/null 2>&1; then
+ AUTOHEADER=autoheader
+ echo "$ac_t""found" 1>&6
+else
+ AUTOHEADER="$missing_dir/missing autoheader"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
+echo "configure:785: checking for working makeinfo" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
+ MAKEINFO=makeinfo
+ echo "$ac_t""found" 1>&6
+else
+ MAKEINFO="$missing_dir/missing makeinfo"
+ echo "$ac_t""missing" 1>&6
+fi
+
+
+
+
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:805: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:835: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:886: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:918: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 929 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:934: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:960: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:965: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:974: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:993: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:1036: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:1089: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+if test "$CC" = "gcc"; then
+ CFLAGS="$CFLAGS -Wall -Werror"
+fi
+
+# Check whether --enable-check or --disable-check was given.
+if test "${enable_check+set}" = set; then
+ enableval="$enable_check"
+ CFLAGS="$CFLAGS -DCHECK=1"
+
+fi
+
+
+# Check whether --enable-profile or --disable-profile was given.
+if test "${enable_profile+set}" = set; then
+ enableval="$enable_profile"
+ CFLAGS="$CFLAGS -pg"
+
+fi
+
+
+# Check whether --enable-user-check or --disable-user-check was given.
+if test "${enable_user_check+set}" = set; then
+ enableval="$enable_user_check"
+ user_check="no"
+else
+ user_check="yes"
+
+fi
+
+
+# Check whether --enable-cron or --disable-cron was given.
+if test "${enable_cron+set}" = set; then
+ enableval="$enable_cron"
+ install_cron="$enableval"
+else
+ install_cron="yes"
+
+fi
+
+
+# Check whether --enable-rc or --disable-rc was given.
+if test "${enable_rc+set}" = set; then
+ enableval="$enable_rc"
+ install_rc="$enableval"
+else
+ install_rc="yes"
+
+fi
+
+
+# Check whether --with-spool or --without-spool was given.
+if test "${with_spool+set}" = set; then
+ withval="$with_spool"
+ SPOOLDIR="$withval"
+else
+ FC_EXPAND_DIR(SPOOLDIR, '${localstatedir}/spool/dlife')
+
+fi
+
+
+# Check whether --with-conf or --without-conf was given.
+if test "${with_conf+set}" = set; then
+ withval="$with_conf"
+ CONFDIR="$withval"
+else
+ FC_EXPAND_DIR(CONFDIR, '${sysconfdir}/dlife')
+
+fi
+
+
+if test "$user_check" = "yes"; then
+ echo $ac_n "checking for dlife group""... $ac_c" 1>&6
+echo "configure:1188: checking for dlife group" >&5
+ if ! grep '^dlife:' /etc/group >/dev/null; then
+ { echo "configure: error: there is no 'dlife' group in /etc/group" 1>&2; exit 1; }
+ fi
+ echo "$ac_t""found" 1>&6
+
+ echo $ac_n "checking for dlife user""... $ac_c" 1>&6
+echo "configure:1195: checking for dlife user" >&5
+ if ! grep '^dlife:' /etc/passwd >/dev/null; then
+ { echo "configure: error: there is no 'dlife' user in /etc/passwd" 1>&2; exit 1; }
+ fi
+ echo "$ac_t""found" 1>&6
+fi
+
+for ac_func in \
+ closedir \
+ getpwnam \
+ getuid \
+ initgroups \
+ nice \
+ opendir \
+ openlog \
+ readdir \
+ setgid \
+ setuid \
+ syslog \
+
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1217: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1222 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1245: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:1271: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 1286 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1292: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 1303 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1309: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 1320 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1326: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+for ac_hdr in \
+ assert.h \
+ dirent.h \
+ errno.h \
+ fcntl.h \
+ grp.h \
+ pwd.h \
+ signal.h \
+ stddef.h \
+ stdint.h \
+ string.h \
+ sys/param.h \
+ sys/types.h \
+ syslog.h \
+ time.h \
+ unistd.h \
+
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1370: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1375 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1380: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+
+echo $ac_n "checking crontab directory""... $ac_c" 1>&6
+echo "configure:1409: checking crontab directory" >&5
+
+case "$install_cron" in
+yes|auto)
+ if test -d $sysconfdir/cron.d; then
+ install_cron=$sysconfdir/cron.d
+ else
+ { echo "configure: error: failed to find a directory to put crontabs in; try --help" 1>&2; exit 1; }
+ fi
+ ;;
+standard)
+ install_cron=/etc/cron.d
+ ;;
+/*)
+ ;;
+no)
+ ;;
+*)
+ { echo "configure: error: unknown parameter given to --enable-cron" 1>&2; exit 1; }
+ ;;
+esac
+
+echo "$ac_t""$install_cron" 1>&6
+CRONDIR=$install_cron
+
+
+
+if test "$install_cron" != "no"; then
+ INSTALL_CRON_TRUE=
+ INSTALL_CRON_FALSE='#'
+else
+ INSTALL_CRON_TRUE='#'
+ INSTALL_CRON_FALSE=
+fi
+
+
+echo $ac_n "checking rc directory""... $ac_c" 1>&6
+echo "configure:1446: checking rc directory" >&5
+
+case "$install_rc" in
+yes|auto)
+ if test -d $sysconfdir/init.d; then
+ install_rc=$sysconfdir/init.d
+ else
+ { echo "configure: error: failed to find a directory to put rc scripts in; try --help" 1>&2; exit 1; }
+ fi
+ ;;
+standard)
+ install_rc=/etc/init.d
+ ;;
+/*)
+ ;;
+no)
+ ;;
+*)
+ { echo "configure: error: unknown parameter given to --enable-rc" 1>&2; exit 1; }
+ ;;
+esac
+
+echo "$ac_t""$install_rc" 1>&6
+RCDIR=$install_rc
+
+
+
+if test "$install_rc" != "no"; then
+ INSTALL_RC_TRUE=
+ INSTALL_RC_FALSE='#'
+else
+ INSTALL_RC_TRUE='#'
+ INSTALL_RC_FALSE=
+fi
+
+echo $ac_n "checking spool directory""... $ac_c" 1>&6
+echo "configure:1482: checking spool directory" >&5
+echo "$ac_t""$SPOOLDIR" 1>&6
+
+echo $ac_n "checking config directory""... $ac_c" 1>&6
+echo "configure:1486: checking config directory" >&5
+echo "$ac_t""$CONFDIR" 1>&6
+
+echo $ac_n "checking for a place to install documentation""... $ac_c" 1>&6
+echo "configure:1490: checking for a place to install documentation" >&5
+if test -d $prefix/share/doc; then
+ DOCDIR=$prefix/share/doc/$PACKAGE-$VERSION
+else
+ DOCDIR=/tmp
+fi
+echo "$ac_t""$DOCDIR" 1>&6
+
+RELEASEDATE=`date +"%d %b %Y"`
+
+
+
+
+
+
+
+
+cat >> confdefs.h <<EOF
+#define SPOOLDIR "$SPOOLDIR"
+EOF
+
+cat >> confdefs.h <<EOF
+#define CONFDIR "$CONFDIR"
+EOF
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "
+ Makefile
+ dlife_client.pl
+ dlife_server.pl
+ dlife.spec
+ index.html
+ config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@ACLOCAL@%$ACLOCAL%g
+s%@AUTOCONF@%$AUTOCONF%g
+s%@AUTOMAKE@%$AUTOMAKE%g
+s%@AUTOHEADER@%$AUTOHEADER%g
+s%@MAKEINFO@%$MAKEINFO%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@CC@%$CC%g
+s%@CPP@%$CPP%g
+s%@INSTALL_CRON_TRUE@%$INSTALL_CRON_TRUE%g
+s%@INSTALL_CRON_FALSE@%$INSTALL_CRON_FALSE%g
+s%@INSTALL_RC_TRUE@%$INSTALL_RC_TRUE%g
+s%@INSTALL_RC_FALSE@%$INSTALL_RC_FALSE%g
+s%@CRONDIR@%$CRONDIR%g
+s%@RCDIR@%$RCDIR%g
+s%@SPOOLDIR@%$SPOOLDIR%g
+s%@CONFDIR@%$CONFDIR%g
+s%@DOCDIR@%$DOCDIR%g
+s%@RELEASEDATE@%$RELEASEDATE%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile
+ dlife_client.pl
+ dlife_server.pl
+ dlife.spec
+ index.html
+ "}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="config.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
--- /dev/null
+# DLIFE (C) 2000 Richard W.M. Jones <rich@annexia.org>
+# and other authors listed in the ``AUTHORS'' file.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# $Id: configure.in,v 1.3 2002/04/05 17:02:25 rich Exp $
+
+AC_INIT(cell.c)
+AM_INIT_AUTOMAKE(dlife, 1.0.0)
+AM_CONFIG_HEADER(config.h)
+
+dnl Check for the basic compile environment.
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_PROG_MAKE_SET
+
+dnl Enable compiler warnings.
+if test "$CC" = "gcc"; then
+ CFLAGS="$CFLAGS -Wall -Werror"
+fi
+
+dnl Check for arguments to configure.
+AC_ARG_ENABLE(
+ check,
+ [ --enable-check Enable extra internal consistency checks (slow)],
+ CFLAGS="$CFLAGS -DCHECK=1"
+)
+
+AC_ARG_ENABLE(
+ profile,
+ [ --enable-profile Enable code profiling],
+ CFLAGS="$CFLAGS -pg"
+)
+
+AC_ARG_ENABLE(
+ user-check,
+ [ --disable-user-check Do not check for existance of dlife account],
+ user_check="no",
+ user_check="yes"
+)
+
+AC_ARG_ENABLE(
+ cron,
+ [ --enable-cron[=layout] Install cron script to run dlife net client
+ 'layout' may be 'auto' (default), 'standard',
+ or a path to crontab directory starting with /
+ --disable-cron Do not install cron script],
+ install_cron="$enableval",
+ install_cron="yes"
+)
+
+AC_ARG_ENABLE(
+ rc,
+ [ --enable-rc[=layout] Install rc script (runs dlife_soup at boot)
+ 'layout' may be 'auto' (default), 'standard',
+ or a path to local rc directory starting with /
+ --disable-rc Do not install rc script],
+ install_rc="$enableval",
+ install_rc="yes"
+)
+
+AC_ARG_WITH(
+ spool,
+ [ --with-spool=DIR Spool directory (default typically /var/spool/dlife)],
+ SPOOLDIR="$withval",
+ FC_EXPAND_DIR(SPOOLDIR, '${localstatedir}/spool/dlife')
+)
+
+AC_ARG_WITH(
+ conf,
+ [ --with-conf=DIR Config directory (default typically /etc/dlife)],
+ CONFDIR="$withval",
+ FC_EXPAND_DIR(CONFDIR, '${sysconfdir}/dlife')
+)
+
+dnl Check for ``dlife'' account.
+if test "$user_check" = "yes"; then
+ AC_MSG_CHECKING([for dlife group])
+ if ! grep '^dlife:' /etc/group >/dev/null; then
+ AC_MSG_ERROR([there is no 'dlife' group in /etc/group])
+ fi
+ AC_MSG_RESULT([found])
+
+ AC_MSG_CHECKING([for dlife user])
+ if ! grep '^dlife:' /etc/passwd >/dev/null; then
+ AC_MSG_ERROR([there is no 'dlife' user in /etc/passwd])
+ fi
+ AC_MSG_RESULT([found])
+fi
+
+dnl Check for available functions.
+AC_CHECK_FUNCS( \
+ closedir \
+ getpwnam \
+ getuid \
+ initgroups \
+ nice \
+ opendir \
+ openlog \
+ readdir \
+ setgid \
+ setuid \
+ syslog \
+ )
+
+dnl Check for header files.
+AC_CHECK_HEADERS( \
+ assert.h \
+ dirent.h \
+ errno.h \
+ fcntl.h \
+ grp.h \
+ pwd.h \
+ signal.h \
+ stddef.h \
+ stdint.h \
+ string.h \
+ sys/param.h \
+ sys/types.h \
+ syslog.h \
+ time.h \
+ unistd.h \
+ )
+
+dnl Check for a place to install the crontab.
+dnl The $install_cron variable will have one of the following possible
+dnl values:
+dnl yes / auto Try to determine cron dir by automatic means
+dnl no Do not install crontab
+dnl standard Use FSSTND layout (/etc/cron.d)
+dnl /path/to/dir/ Use given directory
+dnl After this, $install_cron will contain either a path (beginning
+dnl with /) or "no".
+
+AC_MSG_CHECKING([crontab directory])
+
+case "$install_cron" in
+yes|auto)
+ if test -d $sysconfdir/cron.d; then
+ install_cron=$sysconfdir/cron.d
+ else
+ AC_MSG_ERROR([failed to find a directory to put crontabs in; try --help])
+ fi
+ ;;
+standard)
+ install_cron=/etc/cron.d
+ ;;
+/*)
+ dnl Do nothing.
+ ;;
+no)
+ dnl Do nothing.
+ ;;
+*)
+ AC_MSG_ERROR([unknown parameter given to --enable-cron])
+ ;;
+esac
+
+AC_MSG_RESULT($install_cron)
+CRONDIR=$install_cron
+
+AM_CONDITIONAL(INSTALL_CRON,[test "$install_cron" != "no"])
+
+dnl Check for a place to install rc scripts
+dnl The $install_rc variable will have one of the following possible
+dnl values:
+dnl yes / auto Try to determine rc dir by automatic means
+dnl no Do not install rc script
+dnl standard Use red hat / debian / FSSTND layout (/etc/init.d)
+dnl /path/to/dir/ Use given directory
+dnl After this, $install_rc will contain either a path (beginning
+dnl with /) or "no".
+
+AC_MSG_CHECKING([rc directory])
+
+case "$install_rc" in
+yes|auto)
+ if test -d $sysconfdir/init.d; then
+ install_rc=$sysconfdir/init.d
+ else
+ AC_MSG_ERROR([failed to find a directory to put rc scripts in; try --help])
+ fi
+ ;;
+standard)
+ install_rc=/etc/init.d
+ ;;
+/*)
+ dnl Do nothing.
+ ;;
+no)
+ dnl Do nothing.
+ ;;
+*)
+ AC_MSG_ERROR([unknown parameter given to --enable-rc])
+ ;;
+esac
+
+AC_MSG_RESULT($install_rc)
+RCDIR=$install_rc
+
+AM_CONDITIONAL(INSTALL_RC,[test "$install_rc" != "no"])
+
+AC_MSG_CHECKING([spool directory])
+AC_MSG_RESULT($SPOOLDIR)
+
+AC_MSG_CHECKING([config directory])
+AC_MSG_RESULT($CONFDIR)
+
+dnl Check for a place to install documentation.
+AC_MSG_CHECKING([for a place to install documentation])
+if test -d $prefix/share/doc; then
+ DOCDIR=$prefix/share/doc/$PACKAGE-$VERSION
+else
+ DOCDIR=/tmp
+fi
+AC_MSG_RESULT($DOCDIR)
+
+dnl Release date.
+RELEASEDATE=`date +"%d %b %Y"`
+
+dnl Variables to be substituted.
+AC_SUBST(CRONDIR)
+AC_SUBST(RCDIR)
+AC_SUBST(SPOOLDIR)
+AC_SUBST(CONFDIR)
+AC_SUBST(DOCDIR)
+AC_SUBST(RELEASEDATE)
+
+dnl Variables to be placed in config.h.
+AC_DEFINE_UNQUOTED(SPOOLDIR, "$SPOOLDIR")
+AC_DEFINE_UNQUOTED(CONFDIR, "$CONFDIR")
+
+dnl Generate output files.
+AC_OUTPUT([
+ Makefile
+ dlife_client.pl
+ dlife_server.pl
+ dlife.spec
+ index.html
+ ])
--- /dev/null
+/* DLIFE Copyright (C) 2000 Richard W.M. Jones <rich@annexia.org>
+ * and other authors listed in the ``AUTHORS'' file.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id: crc.c,v 1.1 2002/04/05 14:40:25 rich Exp $
+ */
+
+#include "config.h"
+
+#include "crc.h"
+
+/* Code to do 32-bit CRCs.
+ * Derived from code by Julian Seward (sewardj@cs.man.ac.uk)
+ * Written by Richard W.M. Jones (rich@annexia.org)
+ * Note original copyright messages below ...
+ */
+
+/*--
+ Copyright (C) 1996 by Julian Seward.
+ Department of Computer Science, University of Manchester,
+ Oxford Road, Manchester M13 9PL, UK.
+ email: sewardj@cs.man.ac.uk
+--*/
+
+/*---------------------------------------------------*/
+/*--- 32-bit CRC grunge ---*/
+/*---------------------------------------------------*/
+
+/*--
+ I think this is an implementation of the AUTODIN-II,
+ Ethernet & FDDI 32-bit CRC standard. Vaguely derived
+ from code by Rob Warnock, in Section 51 of the
+ comp.compression FAQ.
+--*/
+
+static crc_t crc32Table[256] = {
+
+ /*-- Ugly, innit? --*/
+
+ 0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
+ 0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
+ 0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
+ 0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
+ 0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
+ 0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
+ 0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
+ 0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
+ 0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
+ 0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
+ 0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
+ 0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
+ 0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
+ 0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
+ 0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
+ 0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
+ 0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
+ 0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
+ 0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
+ 0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
+ 0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
+ 0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
+ 0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
+ 0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
+ 0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
+ 0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
+ 0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
+ 0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
+ 0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
+ 0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
+ 0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
+ 0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
+ 0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
+ 0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
+ 0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
+ 0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
+ 0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
+ 0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
+ 0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
+ 0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
+ 0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
+ 0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
+ 0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
+ 0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
+ 0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
+ 0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
+ 0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
+ 0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
+ 0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
+ 0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
+ 0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
+ 0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
+ 0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
+ 0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
+ 0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
+ 0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
+ 0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
+ 0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
+ 0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
+ 0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
+ 0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
+ 0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
+ 0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
+ 0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
+};
+
+#define UPDATE_CRC(crcVar,cha) \
+{ \
+ crcVar = (crcVar << 8) ^ \
+ crc32Table[(crcVar >> 24) ^ \
+ (cha)]; \
+}
+
+inline crc_t
+incr_compute_crc32 (crc_t crc, byte_t *p, size_t len)
+{
+ while (len)
+ {
+ UPDATE_CRC (crc, *p);
+ p ++;
+ len --;
+ }
+ return crc;
+}
+
+crc_t
+compute_crc32 (byte_t *p, size_t len)
+{
+ return incr_compute_crc32 (0xffffffffUL, p, len);
+}
--- /dev/null
+/* DLIFE Copyright (C) 2000 Richard W.M. Jones <rich@annexia.org>
+ * and other authors listed in the ``AUTHORS'' file.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id: crc.h,v 1.1 2002/04/05 14:40:26 rich Exp $
+ */
+
+#ifndef crc_h
+#define crc_h
+
+#include <stdlib.h>
+
+#include "types.h"
+
+typedef uint32_t crc_t;
+
+extern crc_t compute_crc32 (byte_t *p, size_t len);
+extern crc_t incr_compute_crc32 (crc_t old_crc, byte_t *p, size_t len);
+
+#endif /* crc_h */
--- /dev/null
+dlife (0.0.15-1) unstable; urgency=low
+
+ * Initial Release.
+
+ -- Falk Hueffner <falk@debian.org> Fri, 13 Oct 2000 05:49:22 +0200
+
+Local variables:
+mode: debian-changelog
+End:
--- /dev/null
+/etc/init.d/dlife
+/etc/dlife/client.conf
+/etc/dlife/soup.conf
+/etc/ppp/ip-up.d/9dlife
--- /dev/null
+Source: dlife
+Section: misc
+Priority: optional
+Maintainer: Falk Hueffner <falk@debian.org>
+Standards-Version: 3.0.1
+
+Package: dlife
+Architecture: any
+Depends: ${shlibs:Depends}, perl5, libnet-perl, libhtml-parser-perl, liburi-perl, libmime-base64-perl, libdigest-md5-perl, libwww-perl
+Description: Distributed Artificial Life client
+ DLIFE is a distributed version of Tom S. Ray's Tierra artificial life
+ program. Note that the machine language used is similar to but not
+ compatible with Tierra. Tom Ray talks about his work (as far as I
+ know, never completed) to create a ``Digital Reserve''. The DLIFE
+ project is a development of this.
+ .
+ In other words, it's an alternative to the tedious process of cracking
+ RC5 keys or searching for aliens. You've got a supercomputer on your
+ desk, let's go and create some life ...
+ .
+ It consists of a highly optimized engine for running the artificial
+ life cells in a virtual machine, written in C, and some Perl scripts
+ which can upload and download cells from central ``cell-bank''
+ servers.
--- /dev/null
+Distributed Artificial Life was debianized by Falk Hüffner
+<falk@debian.org>.
+
+It was originally downloaded from <fill in ftp site>. There's a web
+site for it at http://dlife.annexia.org/.
+
+The copyright belongs to its author Richard W.M. Jones
+<rich@annexia.org>.
+
+It is distributed under the terms of the GNU Public License. The full
+text can be found on Debian systems in /usr/share/common-licenses/GPL.
--- /dev/null
+# Run the client to upload cells periodically.
+5 * * * * dlife /usr/bin/dlife_client.pl
--- /dev/null
+usr/bin
+usr/sbin
+etc/ppp/ip-up.d
--- /dev/null
+AUTHORS
+README
+archproc.gif
+archref.html
+index.html
+machineref.html
+servers.txt
--- /dev/null
+dlife_0.0.12-1_alpha.deb misc optional
--- /dev/null
+#! /bin/sh
+#
+# adapted from the dh_make template by Falk Hueffner <falk@debian.org>
+#
+# using a pidfile doesn't work unfortunately, since dlife_soup forks
+#
+
+PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
+DAEMON=/usr/bin/dlife_soup
+NAME=dlife
+DESC='distributed artificial life client'
+
+test -f $DAEMON || exit 0
+
+set -e
+
+case "$1" in
+ start)
+ echo -n "Starting $DESC: "
+ start-stop-daemon --start --quiet --exec $DAEMON
+ echo "$NAME."
+ ;;
+ stop)
+ echo -n "Stopping $DESC: "
+ start-stop-daemon --stop --quiet --exec $DAEMON
+ echo "$NAME."
+ ;;
+ restart|force-reload)
+ echo -n "Restarting $DESC: "
+ start-stop-daemon --stop --quiet --exec $DAEMON
+ sleep 1
+ start-stop-daemon --start --quiet --exec $DAEMON
+ echo "$NAME."
+ ;;
+ *)
+ N=/etc/init.d/$NAME
+ echo "Usage: $N {start|stop|restart|force-reload}" >&2
+ exit 1
+ ;;
+esac
+
+exit 0
--- /dev/null
+# Automatically added by dh_installdocs
+if [ "$1" = "configure" ]; then
+ if [ -d /usr/doc -a ! -e /usr/doc/dlife -a -d /usr/share/doc/dlife ]; then
+ ln -sf ../share/doc/dlife /usr/doc/dlife
+ fi
+fi
+# End automatically added section
+# Automatically added by dh_installinit
+update-rc.d dlife defaults >/dev/null
+/etc/init.d/dlife start
+# End automatically added section
--- /dev/null
+# Automatically added by dh_installinit
+if [ "$1" = "purge" ] ; then
+ update-rc.d dlife remove >/dev/null
+fi
+# End automatically added section
--- /dev/null
+# Automatically added by dh_installdocs
+if [ \( "$1" = "upgrade" -o "$1" = "remove" \) -a -L /usr/doc/dlife ]; then
+ rm -f /usr/doc/dlife
+fi
+# End automatically added section
+# Automatically added by dh_installinit
+/etc/init.d/dlife stop
+# End automatically added section
--- /dev/null
+#!/usr/bin/make -f
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+# This is the debhelper compatability version to use.
+export DH_COMPAT=1
+
+build: build-stamp
+build-stamp:
+ dh_testdir
+
+ ./configure --prefix=/usr --localstatedir=/var --sysconfdir=/etc \
+ --disable-cron --disable-rc --disable-user-check
+ $(MAKE)
+
+ touch build-stamp
+
+clean:
+ dh_testdir
+ dh_testroot
+ rm -f build-stamp
+
+ -$(MAKE) distclean
+
+ dh_clean
+
+install: build
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs
+
+ $(MAKE) DESTDIR=`pwd`/debian/tmp install
+ rm debian/tmp/tmp/* # kludge; installation leaves cruft in /tmp
+ cp debian/9dlife debian/tmp/etc/ppp/ip-up.d
+ chmod a+x debian/tmp/etc/ppp/ip-up.d/9dlife
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+ dh_testdir
+ dh_testroot
+ dh_installdocs
+ dh_installinit
+ dh_installcron
+# dh_installmanpages
+ dh_undocumented
+ dh_installchangelogs
+ dh_link
+ dh_strip
+ dh_compress
+ dh_fixperms
+ dh_installdeb
+ dh_shlibdeps
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install
--- /dev/null
+shlibs:Depends=libc6.1 (>= 2.1.2-1)
--- /dev/null
+#!/bin/sh
+#
+# dlife.rc This shell script takes care of starting and stopping
+# the dlife client.
+#
+# chkconfig: 2345 80 30
+# description: The Distributed Artificial Life client.
+# processname: dlife_soup
+# config: /etc/dlife/soup.conf
+
+# Source function library.
+. /etc/init.d/functions
+
+# Source networking configuration.
+. /etc/sysconfig/network
+
+# Check that networking is up.
+[ ${NETWORKING} = "no" ] && exit 0
+
+[ -f /usr/bin/dlife_soup ] || exit 0
+
+# See how we were called.
+case "$1" in
+ start)
+ # Start daemons.
+ echo -n "Starting dlife: "
+ daemon /usr/bin/dlife_soup
+ echo
+ ;;
+ stop)
+ # Stop daemons.
+ echo -n "Shutting down dlife: "
+ killproc dlife_soup
+ echo
+ ;;
+ restart)
+ $0 stop
+ $0 start
+ ;;
+ status)
+ status dlife_soup
+ ;;
+ *)
+ echo "Usage: dlife.rc {start|stop|restart|status}"
+ exit 1
+esac
+
+exit 0
+
--- /dev/null
+# @configure_input@
+# $Id: dlife.spec.in,v 1.3 2002/04/05 17:07:25 rich Exp $
+
+Summary: Distributed Artificial Life (DLIFE)
+Name: @PACKAGE@
+Version: @VERSION@
+Release: 1
+Copyright: GPL
+Group: Applications/Internet
+Source: @PACKAGE@-@VERSION@.tar.gz
+BuildRoot: /var/tmp/%{name}-%{version}-root
+Requires: perl-libwww-perl
+Requires: perl >= 5.004
+Requires: vixie-cron
+Requires: SysVinit
+
+
+%description
+Distributed Artificial Life is a package for joining your
+computer to a network of computers running a large artificial
+life simulation.
+
+
+%package server
+Summary: Distributed Artificial Life (DLIFE) server
+Group: Applications/Internet
+
+
+%description server
+This package contains the server code for DLIFE.
+
+
+%prep
+%setup -q
+
+
+%build
+CFLAGS="-O" \
+./configure \
+ --prefix=/usr --sysconfdir=/etc --localstatedir=/var \
+ --disable-user-check
+make
+
+
+%install
+rm -rf $RPM_BUILD_ROOT
+mkdir -p $RPM_BUILD_ROOT
+make NO_CHOWN=1 DESTDIR=$RPM_BUILD_ROOT install
+
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+
+%pre
+grep '^dlife:' /etc/group >/dev/null || {
+ echo "There is no 'dlife' group in /etc/group"
+ exit 1;
+}
+grep '^dlife:' /etc/passwd >/dev/null || {
+ echo "There is no 'dlife' user in /etc/passwd"
+ exit 1;
+}
+
+
+%pre server
+grep '^dlife:' /etc/group >/dev/null || {
+ echo "There is no 'dlife' group in /etc/group"
+ exit 1;
+}
+grep '^dlife:' /etc/passwd >/dev/null || {
+ echo "There is no 'dlife' user in /etc/passwd"
+ exit 1;
+}
+
+
+%files
+%defattr(-,root,root)
+%doc /usr/share/doc/@PACKAGE@-@VERSION@/
+@prefix@/bin/dlife_soup
+@prefix@/bin/dlife_client.pl
+%attr(0775,dlife,dlife) @SPOOLDIR@/
+@CONFDIR@/
+%config @CRONDIR@/dlife_client.cron
+@RCDIR@/dlife.rc
+
+
+%files server
+%defattr(-,root,root)
+@prefix@/bin/dlife_server.pl
+%attr(0775,dlife,dlife) @SPOOLDIR@/store/
--- /dev/null
+#!/usr/bin/perl -w
+
+# DLIFE assembler.
+# By Richard W.M. Jones.
+#
+# $Id: dlife_asm.pl,v 1.1 2002/04/05 14:40:26 rich Exp $
+
+use strict;
+
+use Getopt::Long;
+
+my $help;
+
+GetOptions ("help|?" => \$help);
+
+if ($help)
+ {
+ print STDERR "dlife_asm.pl [--help] file.dla [file.dla [...]]\n";
+ exit 1;
+ }
+
+# Read input file(s) and assemble each one. Each input file has the
+# form ``filename.dla'' and we will write a file called ``filename.dlo''.
+foreach my $filename (@ARGV)
+ {
+ my $output = $filename . ".dlo";
+
+ if ($filename =~ m/(.*)\.dla$/)
+ {
+ $output = $1 . ".dlo";
+ }
+
+ open FILE, "<$filename" or die "$filename: $!";
+ open OUT, ">$output" or die "$output: $!";
+
+ while (<FILE>)
+ {
+ # Remove terminating CRs and LFs.
+ s/[\n\r]+//;
+
+ # Ignore blank lines and comments.
+ s/;.*$//;
+ s/^[ \t]*$//;
+ next if m/^$/;
+
+ # Parse the instruction.
+ parse_insn ($_);
+ }
+
+ close FILE;
+ print OUT "\n";
+ close OUT;
+ }
+
+sub parse_insn
+ {
+ my $insn = shift;
+
+ # Trim leading and trailing whitespace.
+ $insn =~ s/^[ \t]+//g;
+ $insn =~ s/[ \t]+$//g;
+
+ # Leading label?
+ if ($insn =~ m/^([01]+):(.*)$/)
+ {
+ my $label = $1;
+ my $rest = $2;
+
+ foreach (split //, $label)
+ {
+ if (m/0/) { print OUT "00" }
+ if (m/1/) { print OUT "01" }
+ }
+
+ parse_insn ($rest);
+ return;
+ }
+
+ # IFZ instruction prefix?
+ if ($insn =~ m/^IFZ[ \t]+(.*)$/i)
+ {
+ my $rest = $1;
+
+ print OUT "07\n";
+
+ parse_insn ($rest);
+ return;
+ }
+ # Empty instruction?
+ elsif ($insn =~ m/^$/)
+ {
+ return;
+ }
+ # Other instruction?
+ elsif ($insn =~ m/^NOP0$/i)
+ {
+ print OUT "00\n";
+ }
+ elsif ($insn =~ m/^NOP1$/i)
+ {
+ print OUT "01\n";
+ }
+ elsif ($insn =~ m/^INC[ \t]+A$/i)
+ {
+ print OUT "02\n";
+ }
+ elsif ($insn =~ m/^DEC[ \t]+A$/i)
+ {
+ print OUT "03\n";
+ }
+ elsif ($insn =~ m/^SHL[ \t]+A$/i)
+ {
+ print OUT "04\n";
+ }
+ elsif ($insn =~ m/^FINDB[ \t](.*)$/i)
+ {
+ print OUT "08\n";
+ parse_pattern ($1);
+ }
+ elsif ($insn =~ m/^FINDF[ \t](.*)$/i)
+ {
+ print OUT "09\n";
+ parse_pattern ($1);
+ }
+ elsif ($insn =~ m/^MALLOC$/i)
+ {
+ print OUT "0A\n";
+ }
+ elsif ($insn =~ m/^DIVIDE$/i)
+ {
+ print OUT "0B\n";
+ }
+ elsif ($insn =~ m/^MOVE[ \t]+\[I\],A$/i)
+ {
+ print OUT "0C\n";
+ }
+ elsif ($insn =~ m/^MOVE[ \t]+A,\[I\]$/i)
+ {
+ print OUT "0D\n";
+ }
+ elsif ($insn =~ m/^DMOVE[ \t]+\[I\],A$/i)
+ {
+ print OUT "0E\n";
+ }
+ elsif ($insn =~ m/^DMOVE[ \t]+A,\[I\]$/i)
+ {
+ print OUT "0F\n";
+ }
+ elsif ($insn =~ m/^XOR[ \t]+([ABIP]),([ABIP])$/i)
+ {
+ my $reg1 = reg2bin ($1);
+ my $reg2 = reg2bin ($2);
+
+ printf OUT ("%02X\n", 16 + ($reg2 << 2) + $reg1);
+ }
+ elsif ($insn =~ m/^PUSH[ \t]+([ABIP])$/i)
+ {
+ my $reg = reg2bin ($1);
+
+ printf OUT ("%02X\n", 32 + $reg);
+ }
+ elsif ($insn =~ m/^POP[ \t]+([ABIP])$/i)
+ {
+ my $reg = reg2bin ($1);
+
+ printf OUT ("%02X\n", 36 + $reg);
+ }
+ # Instruction set macros.
+ elsif ($insn =~ m/MOVE[ \t]+([ABIP]),([ABIP])$/i)
+ {
+ my $reg1 = reg2bin ($1);
+ my $reg2 = reg2bin ($2);
+
+ printf OUT ("%02X", 32 + $reg1); # PUSH reg1
+ printf OUT ("%02X\n", 36 + $reg2); # POP reg2
+ }
+ elsif ($insn =~ m/SWAP[ \t]+([ABIP]),([ABIP])$/i)
+ {
+ my $reg1 = reg2bin ($1);
+ my $reg2 = reg2bin ($2);
+
+ printf OUT ("%02X", 16 + ($reg2 << 2) + $reg1); # XOR reg1, reg2
+ printf OUT ("%02X", 16 + ($reg1 << 2) + $reg2); # XOR reg2, reg1
+ printf OUT ("%02X", 16 + ($reg2 << 2) + $reg1); # XOR reg1, reg2
+ printf OUT ("%02X\n", 16 + ($reg1 << 2) + $reg2); # XOR reg2, reg1
+ }
+ elsif ($insn =~ m/ZERO[ \t]+([ABIP])$/i)
+ {
+ my $reg = reg2bin ($1);
+
+ printf OUT ("%02X\n", 16 + ($reg << 2) + $reg); # XOR reg, reg
+ }
+ elsif ($insn =~ m/ADD[ \t]+([0-9]+),A$/i)
+ {
+ my $n = $1;
+
+ for (my $i = 0; $i < $n; ++$i)
+ {
+ print OUT "02";
+ }
+ print OUT "\n";
+ }
+ elsif ($insn =~ m/MOVE[ \t]+([0-9]+),A$/i)
+ {
+ my $n = $1;
+
+ print OUT "10"; # XOR A,A
+ while ($n > 0)
+ {
+ if (($n & 1) == 1)
+ {
+ print OUT "0402"; # SHL A; INC A
+ }
+ else
+ {
+ print OUT "04"; # SHL A
+ }
+ $n >>= 1;
+ }
+ print OUT "\n";
+ }
+ elsif ($insn =~ m/LOAD[ \t]+([0-9]+),A$/i)
+ {
+ my $n = $1;
+
+ print OUT "222124"; # PUSH I; PUSH B; POP A
+ for (my $i = 0; $i < $n * 2; ++$i)
+ {
+ print OUT "02"; # INC A
+ }
+ print OUT "20260E26\n"; # PUSH A; POP I; DMOVE [I],A; POP I
+ }
+ elsif ($insn =~ m/STORE[ \t]+A,([0-9]+)$/i)
+ {
+ my $n = $1;
+
+ print OUT "22202124"; # PUSH I; PUSH A; PUSH B; POP A
+ for (my $i = 0; $i < $n * 2; ++$i)
+ {
+ print OUT "02"; # INC A
+ }
+ print OUT "2026240F26\n"; # PUSH A; POP I; POP A; DMOVE A,[I]; POP I
+ }
+ elsif ($insn =~ m/^JMP[ \t]+I$/i)
+ {
+ print OUT "2227\n"; # PUSH I; POP P
+ }
+ elsif ($insn =~ m/^JMPF[ \t](.*)$/i)
+ {
+ print OUT "09"; # FINDF
+ parse_pattern ($1);
+ print OUT "2227\n"; # PUSH I; POP P
+ }
+ elsif ($insn =~ m/^JMPB[ \t](.*)$/i)
+ {
+ print OUT "08"; # FINDB
+ parse_pattern ($1);
+ print OUT "2227\n"; # PUSH I; POP P
+ }
+ elsif ($insn =~ m/^JMPZF[ \t](.*)$/i)
+ {
+ print OUT "09"; # FINDF
+ parse_pattern ($1);
+ print OUT "22072726\n"; # PUSH I; IFZ POP P; POP I
+ }
+ elsif ($insn =~ m/^JMPZB[ \t](.*)$/i)
+ {
+ print OUT "08"; # FINDB
+ parse_pattern ($1);
+ print OUT "22072726\n"; # PUSH I; IFZ POP P; POP I
+ }
+ elsif ($insn =~ m/^CALLF[ \t](.*)$/i)
+ {
+ print OUT "2309"; # PUSH P; FINDF
+ parse_pattern ($1);
+ print OUT "2227\n"; # PUSH I; POP P
+ }
+ elsif ($insn =~ m/^CALLB[ \t](.*)$/i)
+ {
+ print OUT "2308"; # PUSH P; FINDB
+ parse_pattern ($1);
+ print OUT "2227\n"; # PUSH I; POP P
+ }
+ elsif ($insn =~ m/^RET[ \t]+([0-9]+)$/i)
+ {
+ my $n = $1;
+ print OUT "24"; # POP A
+ for (my $i = 0; $i < $n + 3; ++$i)
+ {
+ print OUT "02"; # INC A
+ }
+ print OUT "2027\n"; # PUSH A; POP P
+ }
+ elsif ($insn =~ m/^DB[ \t]+([0-9]+)$/i)
+ {
+ my $n = $1;
+ for (my $i = 0; $i < $n; ++$i)
+ {
+ print OUT "FF";
+ }
+ print OUT "\n";
+ }
+ elsif ($insn =~ m/^DW[ \t]+([0-9]+)$/i)
+ {
+ my $n = $1;
+ for (my $i = 0; $i < $n * 2; ++$i)
+ {
+ print OUT "FF";
+ }
+ print OUT "\n";
+ }
+ else
+ {
+ die "$insn: unknown instruction";
+ }
+ }
+
+sub parse_pattern
+ {
+ my $pattern = shift;
+
+ if ($pattern =~ m/^([01]+)$/)
+ {
+ foreach (split //, $1)
+ {
+ if (m/0/) { print OUT "00" }
+ if (m/1/) { print OUT "01" }
+ }
+ }
+ elsif ($pattern =~ m/^~([01]+)$/) # Complemented pattern.
+ {
+ foreach (split //, $1)
+ {
+ if (m/0/) { print OUT "01" }
+ if (m/1/) { print OUT "00" }
+ }
+ }
+ else
+ {
+ die "$pattern: unrecognized pattern argument";
+ }
+ }
+
+sub reg2bin
+ {
+ my $reg = shift;
+
+ if (uc($reg) eq "A") { return 0 }
+ elsif (uc($reg) eq "B") { return 1 }
+ elsif (uc($reg) eq "I") { return 2 }
+ elsif (uc($reg) eq "P") { return 3 }
+ else
+ {
+ die "$reg: unknown register name";
+ }
+ }
--- /dev/null
+# Run the client to upload cells periodically.
+5 * * * * dlife /usr/bin/dlife_client.pl
--- /dev/null
+#!/usr/bin/perl -w -T
+# -*- perl -*-
+# @configure_input@
+
+use strict;
+
+use Getopt::Long;
+use LWP::UserAgent;
+use Socket;
+use IO::Socket;
+use Sys::Hostname;
+use Sys::Syslog qw(:DEFAULT setlogsock);
+
+my $help;
+my $verbose;
+my $config_filename = "@CONFDIR@/client.conf";
+my $spooldir = "@SPOOLDIR@";
+my $client_version = "@VERSION@";
+
+GetOptions ("help|?" => \$help,
+ "verbose" => \$verbose,
+ "config=s" => \$config_filename,
+ "spooldir=s" => \$spooldir);
+
+if ($help)
+ {
+ print STDERR <<EOF;
+dlife_client.pl [--help] [--verbose] \
+ [--spooldir=spooldir] [--config=config_file]
+
+Options:
+ --help Displays this help text.
+ --verbose Lots of messages.
+ --spooldir=spooldir Set spool directory (default is @SPOOLDIR@).
+ --config=config_file Use named configuration file (default is to use
+ @CONFDIR@/client.conf).
+EOF
+ exit 1;
+ }
+
+# Open a connection to syslog.
+setlogsock ("unix");
+openlog ("dlife_client", "", "user");
+
+syslog ("info", "version $client_version starting [conf=$config_filename, spool=$spooldir]");
+
+# Default configuration values.
+my $server_url;
+my @server_zones = ();
+my @servers = ();
+my $max_cells_upload_per_pass = 6;
+my $max_cells_download_per_pass = 4;
+
+# Read configuration file.
+open CONFIG, "<$config_filename" or die "$config_filename: $!";
+
+while (<CONFIG>)
+ {
+ s/[\n\r]*$//;
+ next if /^\s*\#/;
+ next if /^\s*$/;
+
+ if (/^\s*server_url\s+(\S+)\s*$/)
+ {
+ $server_url = $1;
+ print "server_url=$server_url\n" if $verbose;
+ }
+ elsif (/^\s*server_zone\s+(.*)\s*$/)
+ {
+ @server_zones = split /\s+/, $1;
+ print "server_zones=", join (" ", @server_zones), "\n" if $verbose;
+ }
+ elsif (/^\s*server\s+(.*)\s*$/)
+ {
+ @servers = split /\s+/, $1;
+ print "servers=", join (" ", @servers), "\n" if $verbose;
+ }
+ elsif (/^\s*max_cells_upload_per_pass\s+([1-9][0-9]*)\s*$/)
+ {
+ $max_cells_upload_per_pass = $1;
+ }
+ elsif (/^\s*max_cells_download_per_pass\s+([1-9][0-9]*)\s*$/)
+ {
+ $max_cells_download_per_pass = $1;
+ }
+ else
+ {
+ die "unknown configuration option: $_";
+ }
+ }
+
+close CONFIG;
+
+# Load @server_zones into a hash for rapid searching.
+my %server_zones;
+foreach (@server_zones) { $server_zones{$_} = 1; }
+
+# Server URL set or @servers not empty?
+unless ($server_url || @servers)
+ {
+ die "neither server_url and servers was set: cannot do anything";
+ }
+
+# Go to spool directory.
+chdir $spooldir or die "$spooldir: $!";
+
+# Find the list of cells to upload and arrange into a random order.
+my @all_upload_cells = randomize_list (glob_outgoing ());
+
+unless (@all_upload_cells)
+ {
+ syslog ("info", "no cells to upload (is the dlife_soup process running?)");
+ exit;
+ }
+
+# Only upload the first few cells.
+my @upload_cells = @all_upload_cells;
+splice @upload_cells, $max_cells_upload_per_pass;
+
+# If server URL set, then go and download the webpage. Load appropriate
+# server names into @servers.
+if ($server_url)
+ {
+ syslog ("info", "contacting $server_url");
+ print "Contacting $server_url\n" if $verbose;
+
+ my $ua = LWP::UserAgent->new;
+ my $req = HTTP::Request->new ("GET", $server_url);
+ my $rep = $ua->request ($req);
+
+ if ($rep->is_success)
+ {
+ print "Fetched page. Parsing page ...\n" if $verbose;
+
+ # Parse the page.
+ my @lines = split /[\n\r]+/, $rep->content;
+
+ foreach (@lines)
+ {
+ if (/^\s*server\s+(\S*)\s+(.*)\s*$/)
+ {
+ my $server = $1;
+ my @zones = split /\s+/, $2;
+
+ # Is this server in one of our zones?
+ if (@server_zones)
+ {
+ foreach (@zones)
+ {
+ if (exists $server_zones{$_})
+ {
+ push @servers, $server;
+ last;
+ }
+ }
+ }
+ else
+ {
+ push @servers, $server;
+ }
+ }
+ }
+
+ print "Finished parsing page. \@servers = ",
+ join (" ", @servers), "\n"
+ if $verbose;
+ }
+ else
+ {
+ syslog ("error", "could not contact $server_url");
+ print "Could not contact server.\n" if $verbose;
+ }
+ }
+
+# Sort the server list into a random order.
+@servers = randomize_list (@servers);
+
+# Contact each server in turn until we succeed with one of them.
+my $server;
+
+foreach $server (@servers)
+ {
+ alarm 0;
+
+ print "Attempting to connect to $server port 5904\n" if $verbose;
+ syslog ("info", "exchanging cells with $server");
+
+ my $socket = new IO::Socket::INET (PeerAddr => $server,
+ PeerPort => "5904",
+ Proto => "tcp");
+
+ unless ($socket)
+ {
+ syslog ("error", "could not connect to $server");
+ print "Failed to connect.\n" if $verbose;
+ next;
+ }
+
+ print "Connected.\n" if $verbose;
+
+ # Read server and protocol version.
+ alarm 60;
+ $_ = $socket->getline;
+
+ unless (/^DLIFE SERVER\s+([0-9]+\.[0-9]+)\s+([0-9]+\.[0-9]+)/)
+ {
+ print "Unrecognized server greeting.\n" if $verbose;
+ next;
+ }
+
+ my $server_version = $1;
+ my $protocol_version = $2;
+
+ # The only protocol we recognize right now is version 1.x. These
+ # x (minor) revisions will be backwards compatible. If an
+ # incompatibility is introduced in the future, then that will
+ # become version 2.x, 3.x, etc.
+ unless ($protocol_version =~ /^1\./)
+ {
+ print "Unsupported protocol version.\n" if $verbose;
+ next;
+ }
+
+ # Send our client greeting string.
+ $socket->print ("HELO - $client_version\r\n");
+
+ # Wait for OK response.
+ alarm 60;
+ $_ = $socket->getline;
+
+ unless (/^2[0-9][0-9]\s/)
+ {
+ print "Error response from server during HELO.\n" if $verbose;
+ next;
+ }
+
+ # Check for cells to upload, and upload the first few.
+ my $cell_filename;
+
+ foreach $cell_filename (@upload_cells)
+ {
+ print "Uploading $cell_filename ...\n" if $verbose;
+
+ $socket->print ("STOR\r\n");
+
+ # Wait for OK to send response.
+ alarm 60;
+ $_ = $socket->getline;
+
+ unless (/^1[0-9][0-9]\s/)
+ {
+ print "Error response from server during STOR.\n" if $verbose;
+ next;
+ }
+
+ # Send the cell.
+ open CELL, "<$cell_filename" or die "$cell_filename: $!";
+
+ while (<CELL>)
+ {
+ s/[\n\r]*$//;
+ $socket->print ($_, "\r\n");
+ }
+
+ close CELL;
+
+ $socket->print (".\r\n");
+
+ # Wait for OK response from server.
+ alarm 60;
+ $_ = $socket->getline;
+
+ unless (/^2[0-9][0-9]\s/)
+ {
+ print "Error response from server after STOR.\n" if $verbose;
+ next;
+ }
+ }
+
+ # Remove all upload cells in the queue.
+ foreach $cell_filename (@all_upload_cells)
+ {
+ unlink $cell_filename;
+ }
+
+ # Check for cells to download.
+ for (my $i = 0; $i < $max_cells_download_per_pass; ++$i)
+ {
+ print "Downloading ...\n" if $verbose;
+
+ $socket->print ("RETR\r\n");
+
+ # Wait for OK to retrieve response.
+ alarm 60;
+ $_ = $socket->getline;
+
+ unless (/^1[0-9][0-9]\s/)
+ {
+ print "Error response from server during RETR.\n" if $verbose;
+ next;
+ }
+
+ # Retrieve the cell.
+ my $cell = "";
+
+ while (length ($cell) < 8192)
+ {
+ alarm 10;
+ $_ = $socket->getline;
+ alarm 0;
+
+ s/[\n\r]*$//;
+
+ last if $_ eq ".";
+
+ $cell .= $_ . "\n";
+ }
+
+ # Wait for OK response.
+ alarm 60;
+ $_ = $socket->getline;
+
+ unless (/^2[0-9][0-9]\s/)
+ {
+ print "Error response from server after RETR.\n" if $verbose;
+ next;
+ }
+
+ # Save the cell to a file.
+ my $rand = int (rand 1000000000);
+ open CELL, ">incoming/$rand.dlo" or die "incoming/$rand.dlo: $!";
+
+ print CELL $cell;
+
+ close CELL;
+ }
+
+ print "Disconnecting ...\n" if $verbose;
+
+ # Say goodbye.
+ $socket->print ("QUIT\r\n");
+
+ # Wait for OK response from server.
+ alarm 60;
+ $_ = $socket->getline;
+
+ unless (/^2[0-9][0-9]\s/)
+ {
+ print "Error response from server during QUIT.\n" if $verbose;
+ next;
+ }
+
+ # Close socket.
+ $socket->close;
+
+ alarm 0;
+ last;
+ }
+
+syslog ("info", "exit");
+
+exit;
+
+sub randomize_list
+ {
+ for (my $i = 0; $i < @_; ++$i)
+ {
+ my $r = int (rand (@_ - $i));
+
+ if ($r > 0)
+ {
+ # Swap elements $i and $i+$r.
+ my $t = $_[$i+$r];
+ $_[$i+$r] = $_[$i];
+ $_[$i] = $t;
+ }
+ }
+
+ return @_;
+ }
+
+# This function is equivalent to glob ("outgoing/*.dlo"), except that
+# the glob function doesn't work when tainting is enabled, alas.
+sub glob_outgoing
+ {
+ opendir DIR, "outgoing" or die "outgoing: $!";
+ my @names = map { untaint_string ($_) } map { "outgoing/$_" } grep { /\.dlo$/ } readdir DIR;
+ closedir DIR;
+ return @names;
+ }
+
+sub untaint_string
+ {
+ my $s = shift;
+ $s =~ /^(.*)$/;
+ return $1;
+ }
--- /dev/null
+#!/usr/bin/perl -w
+
+# DLIFE disassembler.
+# By Richard W.M. Jones.
+#
+# $Id: dlife_disasm.pl,v 1.1 2002/04/05 14:40:26 rich Exp $
+
+use strict;
+
+use Getopt::Long;
+
+my $help;
+
+GetOptions ("help|?" => \$help);
+
+if ($help)
+ {
+ printf STDERR "dlife_disasm.pl [--help] [file.dlo] > file.dla\n";
+ exit 1;
+ }
+
+# Read the entire input file into memory so that we can do some
+# clever stuff with string regexes.
+my $code = "";
+
+while (<>)
+ {
+ $code .= $_;
+ }
+
+# Remove anything which isn't [0-9a-f].
+$code =~ tr/0-9a-fA-F//cd;
+$code =~ tr/a-f/A-F/;
+
+# Convert code to <xx>.
+$code =~ s/(..)/<$1>/g;
+
+# NOTE: The order of this substitutions IS important.
+
+# CALLB and CALLF macros.
+$code =~ s/<23>(<08>|<09>)((<00>|<01>)+)<22><27>/convert_call ($1, $2)/ge;
+
+# JMPB and JMPF macros.
+$code =~ s/(<08>|<09>)((<00>|<01>)+)<22><27>/convert_jmp ($1, $2)/ge;
+
+# JMPBZ and JMPFZ macros.
+$code =~ s/(<08>|<09>)((<00>|<01>)+)<22><07><27><26>/convert_jmpz ($1, $2)/ge;
+
+# Basic FINDF and FINDB commands.
+$code =~ s/(<08>|<09>)((<00>|<01>)+)/convert_find ($1, $2)/ge;
+
+# Any other patterns are labels.
+$code =~ s/((<00>|<01>)+)/convert_label ($1)/ge;
+
+# MOVE macro.
+$code =~ s/(<2[0-3]>)(<2[4-7]>)/convert_move ($1, $2)/ge;
+
+# SWAP macro. XXX Difficult ...
+
+
+
+
+
+
+
+print $code;
+
+sub convert_call
+ {
+ my $find_code = shift;
+ my $pattern = shift;
+
+ my $insn = $find_code eq "<08>" ? "CALLB" : "CALLF";
+
+ $pattern =~ s/<00>/1/g; # Pattern is complemented.
+ $pattern =~ s/<01>/0/g;
+
+ return "\n\t$insn ~$pattern\n";
+ }
+
+sub convert_jmp
+ {
+ my $find_code = shift;
+ my $pattern = shift;
+
+ my $insn = $find_code eq "<08>" ? "JMPB" : "JMPF";
+
+ $pattern =~ s/<00>/1/g; # Pattern is complemented.
+ $pattern =~ s/<01>/0/g;
+
+ return "\n\t$insn ~$pattern\n";
+ }
+
+sub convert_jmpz
+ {
+ my $find_code = shift;
+ my $pattern = shift;
+
+ my $insn = $find_code eq "<08>" ? "JMPBZ" : "JMPFZ";
+
+ $pattern =~ s/<00>/1/g; # Pattern is complemented.
+ $pattern =~ s/<01>/0/g;
+
+ return "\n\t$insn ~$pattern\n";
+ }
+
+sub convert_find
+ {
+ my $find_code = shift;
+ my $pattern = shift;
+
+ my $insn = $find_code eq "<08>" ? "FINDB" : "FINDF";
+
+ $pattern =~ s/<00>/1/g; # Pattern is complemented.
+ $pattern =~ s/<01>/0/g;
+
+ return "\n\t$insn ~$pattern\n";
+ }
+
+sub convert_label
+ {
+ my $pattern = shift;
+
+ $pattern =~ s/<00>/0/g;
+ $pattern =~ s/<01>/1/g;
+
+ return "\n$pattern:\n";
+ }
+
+sub convert_move
+ {
+ my $push_code = shift;
+ my $pop_code = shift;
+
+ my ($src, $dst);
+ if ($push_code eq "<20>") { $src = "A" }
+ elsif ($push_code eq "<21>") { $src = "B" }
+ elsif ($push_code eq "<22>") { $src = "I" }
+ elsif ($push_code eq "<23>") { $src = "P" }
+ if ($pop_code eq "<24>") { $dst = "A" }
+ elsif ($pop_code eq "<25>") { $dst = "B" }
+ elsif ($pop_code eq "<26>") { $dst = "I" }
+ elsif ($pop_code eq "<27>") { $dst = "P" }
+
+ return "\n\tMOVE $src,$dst\n";
+ }
+
--- /dev/null
+#!/usr/bin/perl -w -T
+# -*- perl -*-
+# @configure_input@
+
+BEGIN {
+ # Close stderr, else inetd sends this back to the client.
+ close STDERR;
+};
+
+use strict;
+
+use Socket;
+use IO::Socket;
+use Sys::Hostname;
+use Sys::Syslog qw(:DEFAULT setlogsock);
+
+$ENV{PATH} = "/usr/bin:/bin";
+delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
+
+my $spooldir = "@SPOOLDIR@";
+my $user = "dlife";
+my $server_version = "@VERSION@";
+my $protocol_version = "1.0";
+my $cells_uploaded = 0;
+my $cells_downloaded = 0;
+my $max_cells_upload_per_pass = 8;
+my $max_cells_download_per_pass = 8;
+
+my $hostname = hostname ();
+
+# Open a connection to syslog.
+setlogsock ("unix");
+openlog ("dlife_server", "pid,ndelay", "user");
+
+# Chroot into the spool directory and change our UID/GID so we are safe.
+my ($login, $pass, $uid, $gid) = getpwnam ($user)
+ or die "$user: user not found in password file";
+
+chroot $spooldir or die "chroot $spooldir: $!";
+
+$) = $gid;
+$> = $uid;
+
+die "could not change UID successfully: $!" unless $> == $uid && $) == $gid;
+
+chdir "/store" or die "$spooldir/store: $!";
+
+# Pull out connection information.
+my $peername = getpeername STDIN;
+my ($peerport, $peeraddr) = unpack_sockaddr_in ($peername);
+my $peeraddrstring = inet_ntoa ($peeraddr);
+
+my $peerhostname;
+
+my $revhostname = gethostbyaddr ($peeraddr, AF_INET);
+if ($revhostname)
+ {
+ my $ipaddr = gethostbyname ($revhostname);
+
+ if ($ipaddr && inet_ntoa ($ipaddr) eq $peeraddrstring)
+ {
+ $peerhostname = $revhostname;
+ }
+ }
+
+# Log connection information.
+syslog ("info", "received connection from $peeraddrstring:$peerport" .
+ ($peerhostname ? " ($peerhostname)" : ""));
+
+$| = 1;
+
+# Send greeting to client.
+print "DLIFE SERVER $server_version $protocol_version\r\n";
+
+# Loop, waiting for commands from the client.
+for (;;)
+ {
+ alarm 60;
+ $_ = <STDIN>;
+
+ # Remove trailing \r\n.
+ s/[\r\n]+$//;
+
+ if (/^HELO\s+(.*)\s+(.*)$/)
+ {
+ do_HELO_command ($1, $2);
+ }
+ elsif (/^STOR$/)
+ {
+ do_STOR_command ();
+ }
+ elsif (/^RETR$/)
+ {
+ do_RETR_command ();
+ }
+ elsif (/^QUIT$/)
+ {
+ print "200 Goodbye.\r\n";
+ last; # Exit the loop.
+ }
+ else
+ {
+ # Unknown command. Return an error message.
+ print "500 Unknown command.\r\n";
+ }
+ }
+
+exit 0;
+
+sub do_HELO_command
+ {
+ my $remote_hostname = shift;
+ my $remote_client_version = shift;
+
+ syslog ("info", "client software version: $remote_client_version");
+
+ # Do nothing with this information for now.
+ print "200 Hello.\r\n";
+ }
+
+sub do_STOR_command
+ {
+ if ($cells_uploaded > $max_cells_upload_per_pass)
+ {
+ print "500 Too many cells uploaded in this pass.\r\n";
+ return;
+ }
+
+ print "100 OK. Send the cell, terminated by . <CR> <LF> on a line of its own.\r\n";
+
+ # Read in the cell.
+ my $cell = "";
+
+ while (length ($cell) < 8192)
+ {
+ alarm 10;
+ $_ = <STDIN>;
+ alarm 0;
+
+ s/[\n\r]*$//;
+
+ last if $_ eq ".";
+
+ $cell .= $_ . "\n";
+ }
+
+ # Save the cell to a file.
+ my $rand = int (rand 1000000000);
+ open CELL, ">$rand.dlo" or die "$rand.dlo: $!";
+
+ print CELL $cell;
+
+ close CELL;
+
+ syslog ("info", "received cell $rand.dlo");
+
+ $cells_uploaded ++;
+ print "200 Cell uploaded OK.\r\n";
+ }
+
+sub do_RETR_command
+ {
+ if ($cells_downloaded > $max_cells_download_per_pass)
+ {
+ print "500 Too many cells downloaded in this pass.\r\n";
+ return;
+ }
+
+ # Find a cell at random.
+ my @cells = glob_cells ();
+ if (@cells == 0)
+ {
+ print "400 I have no cells to send you. Try again later.\r\n";
+ return;
+ }
+
+ my $r = rand @cells;
+ my $cell_filename = $cells[$r];
+
+ unless (open CELL, "<$cell_filename")
+ {
+ print "400 Another process grabbed that cell before I could send it. Try again.\r\n";
+ return;
+ }
+
+ # Send it.
+ print "100 OK. Sending you a cell now.\r\n";
+
+ syslog ("info", "sending cell $cell_filename");
+
+ while (<CELL>)
+ {
+ s/[\n\r]+$//;
+ print $_, "\r\n";
+ }
+
+ close CELL;
+
+ unlink $cell_filename;
+
+ print ".\r\n";
+
+ $cells_downloaded ++;
+ print "200 Finished sending the cell.\r\n";
+ }
+
+# This function is equivalent to glob ("*.dlo"), except that
+# the glob function doesn't work when tainting is enabled, alas.
+sub glob_cells
+ {
+ opendir DIR, "." or die "$spooldir/store: $!";
+ my @names = map { untaint_string ($_) } grep { /\.dlo$/ } readdir DIR;
+ closedir DIR;
+ return @names;
+ }
+
+sub untaint_string
+ {
+ my $s = shift;
+ $s =~ /^(.*)$/;
+ return $1;
+ }
--- /dev/null
+/* DLIFE Copyright (C) 2000 Richard W.M. Jones <rich@annexia.org>
+ * and other authors listed in the ``AUTHORS'' file.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id: dlink.h,v 1.1 2002/04/05 14:40:26 rich Exp $
+ */
+
+#ifndef dlink_h
+#define dlink_h
+
+/* This was snarfed from the source for Python 1.5. */
+#ifdef HAVE_STDDEF_H
+#include <stddef.h>
+#endif
+
+#ifndef offsetof
+#define offsetof(type, member) ( (int) & ((type*)0) -> member )
+#endif
+
+typedef struct dlink_list_element
+{
+ void *next;
+ void *prev;
+} dlink_list_element_t;
+
+typedef struct dlink_list
+{
+ void *first;
+ void *last;
+ int offset;
+} dlink_list_t;
+
+#define DLINK_LIST_INIT(offset) { 0, 0, (offset) }
+
+#define _DLINK_ELEMENT_PTRS(element,list) ((dlink_list_element_t *) ((element) + (list)->offset))
+#define _DLINK_FIRST_PTRS(list) _DLINK_ELEMENT_PTRS((list)->first,(list))
+#define _DLINK_LAST_PTRS(list) _DLINK_ELEMENT_PTRS((list)->last,(list))
+
+extern inline void
+dlink_list_init (dlink_list_t *list, int offset)
+{
+ list->first = list->last = 0;
+ list->offset = offset;
+}
+
+extern inline void
+insert_before_first (void *element, dlink_list_t *list)
+{
+ dlink_list_element_t *eptrs = _DLINK_ELEMENT_PTRS (element, list);
+
+ eptrs->prev = 0;
+ eptrs->next = list->first;
+ if (list->first)
+ _DLINK_FIRST_PTRS(list)->prev = element;
+ else
+ list->last = element;
+ list->first = element;
+}
+
+extern inline void
+insert_before_last (void *element, dlink_list_t *list)
+{
+ dlink_list_element_t *eptrs = _DLINK_ELEMENT_PTRS (element, list);
+
+ eptrs->next = 0;
+ eptrs->prev = list->last;
+ if (list->last)
+ _DLINK_LAST_PTRS(list)->next = element;
+ else
+ list->first = element;
+ list->last = element;
+}
+
+extern inline void
+move_towards_last (void *e, dlink_list_t *list)
+{
+ dlink_list_element_t *eptrs = _DLINK_ELEMENT_PTRS (e, list);
+
+ void *e0 = eptrs->prev;
+ dlink_list_element_t *e0ptrs = _DLINK_ELEMENT_PTRS (e0, list);
+
+ void *e1 = eptrs->next;
+ dlink_list_element_t *e1ptrs = _DLINK_ELEMENT_PTRS (e1, list);
+
+ void *e2 = e1ptrs->next;
+ dlink_list_element_t *e2ptrs = _DLINK_ELEMENT_PTRS (e2, list);
+
+ /* The elements are: e0 <---> e <---> e1 <---> e2.
+ *
+ * We know that e and e1 exist, but e0 and e2 may or may not exist.
+ *
+ * We want the arrangement to be:
+ * e0 <---> e1 <---> e <---> e2.
+ */
+ e1ptrs->prev = e0;
+ if (e0)
+ e0ptrs->next = e1;
+ else
+ list->first = e1;
+
+ e1ptrs->next = e;
+ eptrs->prev = e1;
+
+ eptrs->next = e2;
+ if (e2)
+ e2ptrs->prev = e;
+ else
+ list->last = e;
+}
+
+extern inline void
+remove_element (void *element, dlink_list_t *list)
+{
+ dlink_list_element_t *eptrs = _DLINK_ELEMENT_PTRS (element, list);
+
+ void *eprev = eptrs->prev;
+ dlink_list_element_t *eprevptrs = _DLINK_ELEMENT_PTRS (eprev, list);
+
+ void *enext = eptrs->next;
+ dlink_list_element_t *enextptrs = _DLINK_ELEMENT_PTRS (enext, list);
+
+ if (eptrs->next)
+ enextptrs->prev = eprev;
+ else
+ list->last = eprev;
+
+ if (eptrs->prev)
+ eprevptrs->next = enext;
+ else
+ list->first = enext;
+}
+
+#endif /* dlink_h */
--- /dev/null
+/* DLIFE Copyright (C) 2000 Richard W.M. Jones <rich@annexia.org>
+ * and other authors listed in the ``AUTHORS'' file.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id: exec.c,v 1.2 2002/04/05 16:47:12 rich Exp $
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+
+#include "cell.h"
+#include "random.h"
+#include "params.h"
+#include "soup.h"
+
+#define TRACE 0
+
+#if TRACE
+static void trace (const struct cell *cell, int insn);
+#endif
+
+unsigned long long cell_cycle = 0;
+
+static inline int
+get_pattern_length (struct state *state, const struct cell *cell)
+{
+ int p = cell->p;
+ int c;
+
+ /* XXX Maximum pattern length? */
+ /* XXX What if pattern exceeds limits of the cell? */
+ while ((c = get_soup (state, cell->frag, p) & 0x3F) == 0 || c == 1)
+ {
+ p++;
+ }
+
+ return p - cell->p;
+}
+
+static inline int
+check_access (struct state *state, const struct cell *cell, reg_t raddr)
+{
+ if (raddr >= 0 && raddr < cell->frag->len) /* In mother? */
+ return 1;
+ if (cell->daughter) /* In daughter? */
+ {
+ int offset = cell->daughter->frag->base - cell->frag->base;
+
+ /* Be careful with the wrap-around case here. */
+ if (((raddr - offset) & (state->soup_size - 1)) >= 0 &&
+ ((raddr - offset) & (state->soup_size - 1)) < cell->daughter->frag->len)
+ return 1;
+ }
+ return 0;
+}
+
+static inline int
+check_exec_access (struct state *state, const struct cell *cell, reg_t raddr)
+{
+ if (raddr >= 0 && raddr < cell->frag->len) /* In mother? */
+ return 1;
+ return 0;
+}
+
+static inline void
+push (struct cell *cell, reg_t v)
+{
+ cell->sp = (cell->sp+1) & (STACK_SIZE-1);
+ cell->stack[cell->sp] = v;
+}
+
+static inline void
+pop (struct cell *cell, reg_t *va)
+{
+ *va = cell->stack[cell->sp];
+ cell->sp = (cell->sp-1) & (STACK_SIZE-1);
+}
+
+void
+exec_insn (struct state *state, struct cell *cell)
+{
+ /* Increment cycle counters. */
+ state->cell_cycle++;
+ cell->cycle++;
+
+ /* State? */
+ if (cell->state == state_exec)
+ {
+ int insn, error;
+
+ next:
+ /* Fetch next insn. */
+ if (check_exec_access (state, cell, cell->p) ||
+ chance (access_control_failure))
+ {
+ insn = get_soup (state, cell->frag, cell->p);
+ }
+ else
+ {
+ INC_ERRORS (state, cell);
+
+ /* Increment PC */
+ cell->p++;
+
+ return;
+ }
+
+ /* By doing this we allow the cell to use the top two bits of
+ * each instruction byte for its own purposes. DNA uses a similar
+ * technique - it can mark up basic sequences by adding its
+ * own arbitrary chemical markers to each base.
+ */
+ insn &= 0x3f;
+
+#if TRACE
+ trace (cell, insn);
+#endif
+
+ if (chance (soup_fetch_failure))
+ {
+ insn = get_rand_byte () & 0x3f;
+ }
+
+ /* Increment PC */
+ if (!chance (inc_pc_failure))
+ {
+ cell->p++;
+ }
+
+ /* Is this insn going to generate an error? Handle that case
+ * separately (don't disturb the fast path).
+ */
+ error = chance (insn_exec_failure);
+
+ if (!error)
+ {
+ switch (insn)
+ {
+ case 0: /* NOP0 */
+ case 1: /* NOP1 */
+ return; /* Ignore. */
+ case 2: /* INC A */
+ cell->a++;
+ return;
+ case 3: /* DEC A */
+ cell->a--;
+ return;
+ case 4: /* SHL A */
+ cell->a <<= 1;
+ return;
+ case 7: /* IFZ */
+ if (cell->a == 0)
+ goto next; /* Fetch and execute next instruction. */
+ /* Else skip next insn. */
+ cell->p++;
+ return;
+ case 8: /* FINDB */
+ if ((cell->plen = get_pattern_length (state, cell)) > 0)
+ {
+ cell->state = state_find;
+ cell->dir = -1;
+ cell->i = cell->p - 2;
+ cell->lim = FIND_LENGTH_LIMIT;
+ }
+ else
+ {
+ INC_ERRORS (state, cell);
+ cell->i = 0;
+ }
+ return;
+ case 9: /* FINDF */
+ if ((cell->plen = get_pattern_length (state, cell)) > 0)
+ {
+ cell->state = state_find;
+ cell->dir = 1;
+ cell->i = cell->p + cell->plen + 1;
+ cell->lim = FIND_LENGTH_LIMIT;
+ }
+ else
+ {
+ INC_ERRORS (state, cell);
+ cell->i = 0;
+ }
+ return;
+ case 0x0a: /* MALLOC */
+ if (!cell->daughter &&
+ cell->a >= MIN_CELL_SIZE && cell->a <= MAX_CELL_SIZE)
+ {
+ struct soup_frag *frag
+ = soup_frag_malloc (state, cell->frag, cell->a);
+ if (frag)
+ {
+ cell->daughter
+ = cell_malloc (state, cell, frag);
+ /* Calculate relative address of daughter */
+ cell->i
+ = cell->daughter->frag->base
+ - cell->frag->base;
+#if 0
+ printf ("MALLOC: dfb = %d, fb = %d, i = %d\n",
+ cell->daughter->frag->base,
+ cell->frag->base,
+ cell->i);
+#endif
+ }
+ else
+ {
+ /* INC_ERRORS (state, cell); -- Dubious? */
+ cell->i = 0;
+ }
+ }
+ else
+ {
+ INC_ERRORS (state, cell);
+ cell->i = 0;
+ }
+ return;
+ case 0x0b: /* DIVIDE */
+ if (cell->daughter)
+ {
+ cell_divide (state, cell, cell->daughter);
+ cell_activate (state, cell->daughter);
+ cell->daughter = 0;
+ }
+ else
+ {
+ INC_ERRORS (state, cell);
+ cell->i = 0;
+ }
+ return;
+ case 0x0c: /* MOVE [I],A */
+ cell->a = get_soup (state, cell->frag, cell->i);
+ return;
+ case 0x0d: /* MOVE A,[I] */
+ if (check_access (state, cell, cell->i) ||
+ chance (access_control_failure))
+ {
+ set_soup (state, cell->frag, cell->a, cell->i);
+ }
+ else
+ {
+ INC_ERRORS (state, cell);
+ }
+ return;
+ case 0x0e: /* DMOVE [I],A */
+ cell->a = get_soup (state, cell->frag, cell->i) << 8;
+ cell->a |= get_soup (state, cell->frag, cell->i+1);
+ return;
+ case 0x0f: /* DMOVE A,[I] */
+ if ((check_access (state, cell, cell->i) &&
+ check_access (state, cell, cell->i+1)) ||
+ chance (access_control_failure))
+ {
+ set_soup (state, cell->frag, cell->a >> 8, cell->i);
+ set_soup (state, cell->frag, cell->a & 0xff, cell->i+1);
+ }
+ else
+ {
+ INC_ERRORS (state, cell);
+ }
+ return;
+ case 0x10: /* XOR A,A (ie. ZERO A) */
+ cell->a = 0; return;
+ case 0x11: /* XOR B,A */
+ cell->a ^= cell->b; return;
+ case 0x12: /* XOR I,A */
+ cell->a ^= cell->i; return;
+ case 0x13: /* XOR P,A */
+ cell->a ^= cell->p; return;
+ case 0x14: /* XOR A,B */
+ cell->b ^= cell->a; return;
+ case 0x15: /* XOR B,B (ie. ZERO B) */
+ cell->b = 0; return;
+ case 0x16: /* XOR I,B */
+ cell->b ^= cell->i; return;
+ case 0x17: /* XOR P,B */
+ cell->b ^= cell->p; return;
+ case 0x18: /* XOR A,I */
+ cell->i ^= cell->a; return;
+ case 0x19: /* XOR B,I */
+ cell->i ^= cell->b; return;
+ case 0x1a: /* XOR I,I (ie. ZERO I) */
+ cell->i = 0; return;
+ case 0x1b: /* XOR P,I */
+ cell->i ^= cell->p; return;
+ /* Surely these next three instructions will never be used ... */
+ case 0x1c: /* XOR A,P */
+ cell->p ^= cell->a; return;
+ case 0x1d: /* XOR B,P */
+ cell->p ^= cell->b; return;
+ case 0x1e: /* XOR I,P */
+ cell->p ^= cell->i; return;
+ case 0x1f: /* XOR P,P (ie. ZERO P) */
+ cell->p = 0; return;
+ case 0x20: /* PUSH A */
+ push (cell, cell->a);
+ return;
+ case 0x21: /* PUSH B */
+ push (cell, cell->b);
+ return;
+ case 0x22: /* PUSH I */
+ push (cell, cell->i);
+ return;
+ case 0x23: /* PUSH P */
+ push (cell, cell->p);
+ return;
+ case 0x24: /* POP A */
+ pop (cell, &cell->a);
+ return;
+ case 0x25: /* POP B */
+ pop (cell, &cell->b);
+ return;
+ case 0x26: /* POP I */
+ pop (cell, &cell->i);
+ return;
+ case 0x27: /* POP P */
+ pop (cell, &cell->p);
+ return;
+
+ default: /* Unknown instruction. */
+ INC_ERRORS (state, cell);
+ return;
+ }
+ }
+ else
+ {
+ /* Slow path: insn will execute in error. */
+ switch (insn)
+ {
+ case 2: /* INC A */
+ if (chance (2))
+ cell->a += 2;
+ return;
+ case 3: /* DEC A */
+ if (chance (2))
+ cell->a -= 2;
+ return;
+ case 4: /* SHL A */
+ if (chance (2))
+ cell->a <<= 2;
+ return;
+ case 7: /* IFZ */
+ if (chance (2))
+ goto next; /* Fetch and execute next instruction. */
+ /* Else skip next insn. */
+ cell->p++;
+ return;
+ case 8: /* FINDB */
+ if (chance (2))
+ cell->i = 0;
+ return;
+ case 9: /* FINDF */
+ if (chance (2))
+ cell->i = 0;
+ return;
+ case 0x0c: /* MOVE [I],A */
+ cell->a = get_soup (state, cell->frag, cell->i);
+ if (chance (2))
+ cell->a++;
+ else
+ cell->a--;
+ return;
+ case 0x0d: /* MOVE A,[I] */
+ {
+ int i = chance (4);
+ switch (i)
+ {
+ case 0:
+ set_soup (state, cell->frag, cell->a+1, cell->i);
+ return;
+ case 1:
+ set_soup (state, cell->frag, cell->a-1, cell->i);
+ return;
+ case 2:
+ set_soup (state, cell->frag, cell->a, cell->i+1);
+ return;
+ case 3:
+ set_soup (state, cell->frag, cell->a, cell->i-1);
+ return;
+ }
+ return;
+ }
+ case 0x0e: /* DMOVE [I],A */
+ cell->a = get_soup (state, cell->frag, cell->i) << 8;
+ cell->a |= get_soup (state, cell->frag, cell->i+1);
+ if (chance (2))
+ cell->a++;
+ else
+ cell->a--;
+ return;
+ case 0x0f: /* DMOVE A,[I] */
+ {
+ int i = chance (4);
+ switch (i)
+ {
+ case 0:
+ set_soup (state, cell->frag, (cell->a+1) >> 8, cell->i);
+ set_soup (state, cell->frag, (cell->a+1) & 0xFF, cell->i+1);
+ return;
+ case 1:
+ set_soup (state, cell->frag, (cell->a-1) >> 8, cell->i);
+ set_soup (state, cell->frag, (cell->a-1) & 0xFF, cell->i+1);
+ return;
+ case 2:
+ set_soup (state, cell->frag, cell->a >> 8, cell->i+1);
+ set_soup (state, cell->frag, cell->a & 0xFF, cell->i+2);
+ return;
+ case 3:
+ set_soup (state, cell->frag, cell->a >> 8, cell->i-1);
+ set_soup (state, cell->frag, cell->a & 0xFF, cell->i);
+ return;
+ }
+ return;
+ }
+ case 0x10: /* XOR ... */
+ return;
+ case 0x11:
+ cell->a = cell->b; return;
+ case 0x12:
+ cell->a = cell->i; return;
+ case 0x13:
+ cell->a = cell->p; return;
+ case 0x14:
+ cell->b = cell->a; return;
+ case 0x15:
+ return;
+ case 0x16:
+ cell->b = cell->i; return;
+ case 0x17:
+ cell->b = cell->p; return;
+ case 0x18:
+ cell->i = cell->a; return;
+ case 0x19:
+ cell->i = cell->b; return;
+ case 0x1a:
+ return;
+ case 0x1b:
+ cell->i = cell->p; return;
+ case 0x1c:
+ cell->p = cell->a; return;
+ case 0x1d:
+ cell->p = cell->b; return;
+ case 0x1e:
+ cell->p = cell->i; return;
+ case 0x1f:
+ return;
+ }
+ }
+ }
+ else /* cell->state == state_find */
+ {
+ /* During finds,
+ * cell->p == address of pattern complement to match
+ * cell->plen == length of pattern
+ * cell->i == current address of search
+ * cell->dir == direction of search (-1 or 1)
+ * cell->lim == number of steps before we give up
+ */
+ int i;
+
+#if TRACE
+ trace (cell, -1);
+#endif
+
+ for (i = 0; i < cell->plen; ++i)
+ {
+ int pat = get_soup (state, cell->frag, cell->p+i);
+ int mat = get_soup (state, cell->frag, cell->i+i);
+ if (pat > 1 || mat > 1 || pat == mat)
+ {
+ /* Not matched: continue searching. */
+ cell->i += cell->dir;
+ cell->lim--;
+ if (cell->lim == 0)
+ {
+ /* Give up. */
+ cell->i = 0;
+ INC_ERRORS (state, cell);
+ cell->state = state_exec;
+ cell->p += cell->plen;
+ return;
+ }
+ return;
+ }
+ } /* for */
+
+ /* Pattern matched! */
+ cell->p += cell->plen;
+ cell->state = state_exec;
+ return;
+ }
+}
+
+#if TRACE
+static void
+trace (const struct cell *cell, int insn)
+{
+ if (cell->state == state_exec)
+ {
+ printf ("x %p A:%d B:%d I:%d P:%d St:[%d %d %d..] e:%d [%p] ",
+ cell, cell->a, cell->b, cell->i, cell->p,
+ cell->stack[cell->sp],
+ cell->stack[(cell->sp-1) & (STACK_SIZE-1)],
+ cell->stack[(cell->sp-2) & (STACK_SIZE-1)],
+ cell->errors,
+ cell->daughter);
+ switch (insn)
+ {
+ case 0: printf ("NOP0"); break;
+ case 1: printf ("NOP1"); break;
+ case 2: printf ("INC A"); break;
+ case 3: printf ("DEC A"); break;
+ case 4: printf ("SHL A"); break;
+ case 7: printf ("IFZ"); break;
+ case 8: printf ("FINDB"); break;
+ case 9: printf ("FINDF"); break;
+ case 10: printf ("MALLOC"); break;
+ case 11: printf ("DIVIDE"); break;
+ case 12: printf ("MOVE [I],A"); break;
+ case 13: printf ("MOVE A,[I]"); break;
+ case 14: printf ("DMOVE [I],A"); break;
+ case 15: printf ("DMOVE A,[I]"); break;
+ case 16: case 17: case 18: case 19:
+ case 20: case 21: case 22: case 23:
+ case 24: case 25: case 26: case 27:
+ case 28: case 29: case 30: case 31:
+ printf ("XOR %c,%c", "ABIP"[insn&3], "ABIP"[(insn>>2)&3]); break;
+ case 32: case 33: case 34: case 35:
+ printf ("PUSH %c", "ABIP"[insn&3]); break;
+ case 36: case 37: case 38: case 39:
+ printf ("POP %c", "ABIP"[insn&3]); break;
+ default: printf ("unknown %d", insn); break;
+ }
+ printf ("\n");
+ }
+ else
+ {
+ printf ("f %p I:%d P:%d dir:%d plen:%d lim:%d\n",
+ cell, cell->i, cell->p, cell->dir, cell->plen, cell->lim);
+ }
+}
+#endif
--- /dev/null
+;; GOD CELL
+;; BY RICHARD W.M. JONES
+
+00001: ; Marks beginning of the cell.
+
+ JMPF ~00011 ; Jump to start of the cell code
+ ; proper.
+
+00010: ; Marks start of local variables.
+ DW 4 ; Local variable storage.
+
+ ; This is the main cell program.
+
+00011: ; Marks the start of the cell code.
+
+ ; When debugging, use this canard to detect stack underflows.
+ ;MOVE 65535,A
+ ;PUSH A
+
+ FINDB ~00010 ; Find beginning of local variables.
+ MOVE I,A ; Add length of label.
+ ADD 5,A
+ MOVE A,B ; Initialize base register.
+ FINDB ~00001 ; Find beginning address of cell.
+ MOVE I,A
+ STORE A,0 ; Save it for later.
+ FINDF ~01111 ; Find end address of cell.
+ MOVE I,A
+ ADD 5,A ; Add length of final label.
+ STORE A,1 ; Save it for later.
+
+ CALLF ~00100 ; Call subroutine to subtract
+ ; var 0 from var 1 and store in var 2.
+
+ LOAD 2,A ; Load the computed length.
+ MALLOC ; Allocate memory for the daughter.
+ MOVE I,A
+ JMPZB ~00011 ; If allocation failed, start again.
+ STORE A,3 ; Store the daughter's address in 3.
+
+ CALLF ~00110 ; Call subroutine to do the copy.
+
+ DIVIDE ; Break off the daughter cell.
+
+ JMPB ~00011 ; Repeat forever!
+
+ ; This subroutine subtracts var 0 from var 1 and stores the
+ ; resulting value in var 2.
+
+00100:
+ LOAD 1,A ; Copy var 1 into var 2
+ STORE A,2
+ LOAD 0,A ; A <- amount to subtract
+00101: JMPZF ~01001 ; Loop until A == 0
+ PUSH A
+ LOAD 2,A ; Subtract 1 from var 2.
+ DEC A
+ STORE A,2
+ POP A
+ DEC A
+ JMPB ~00101
+01001: RET 5
+
+ ; This subroutine copies var 2 bytes from [var 0] to [var 3] (ie.
+ ; from the mother to the daughter).
+
+00110:
+ LOAD 2,A ; Number of bytes to copy.
+00111: JMPZF ~01000 ; Leave loop when A == 0.
+ PUSH A
+ LOAD 0,A ; Get source address.
+ MOVE A,I
+ MOVE [I],A ; Get item to copy from source.
+ PUSH A
+ LOAD 3,A ; Get destination address.
+ MOVE A,I
+ POP A
+ MOVE A,[I] ; Store item at destination addr.
+ LOAD 0,A ; Increment source address.
+ INC A
+ STORE A,0
+ LOAD 3,A ; Increment destination address.
+ INC A
+ STORE A,3
+ POP A
+ DEC A
+ JMPB ~00111
+01000: RET 5
+
+01111: ; Marks end of the cell.
--- /dev/null
+00000000010901010100002227
+0000000100FFFFFFFFFFFFFFFF
+000000010108
+01010100012224
+0202020202
+2025
+08
+01010101002224
+222021242026240F26
+09
+01000000002224
+0202020202
+2220212402022026240F26
+230901010001012227
+2221240202020220260E26
+0A
+2224
+08010101000022072726
+222021240202020202022026240F26
+230901010000012227
+0B
+0801010100002227
+0000010000222124020220260E26
+22202124020202022026240F26
+22212420260E26
+000001000109010001010022072726
+20
+2221240202020220260E26
+03
+22202124020202022026240F26
+24
+03
+0801010001002227
+00010000012402020202020202022027
+00000101002221240202020220260E26
+000001010109010001010122072726
+20
+22212420260E26
+2026
+0C
+20
+22212402020202020220260E26
+2026
+24
+0D
+22212420260E26
+02
+222021242026240F26
+22212402020202020220260E26
+02
+222021240202020202022026240F26
+24
+03
+0801010000002227
+00010000002402020202020202022027
+0001010101
--- /dev/null
+/* DLIFE Copyright (C) 2000 Richard W.M. Jones <rich@annexia.org>
+ * and other authors listed in the ``AUTHORS'' file.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id: image.c,v 1.2 2002/04/05 16:47:12 rich Exp $
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "image.h"
+#include "state.h"
+#include "cell.h"
+#include "soup.h"
+
+#define FILE_SAVE_VERSION 1
+
+static void global_state_save (struct state *state, FILE *fp);
+static void global_state_load (struct state *state, FILE *fp);
+
+struct state *
+image_load (const char *filename, int _soup_size, int thread_num)
+{
+ FILE *fp;
+ struct state *state;
+
+ fp = fopen (filename, "r");
+ if (fp == 0) { perror (filename); return 0; }
+
+ state = state_malloc (_soup_size, thread_num);
+
+ global_state_load (state, fp);
+ cell_state_load (state, fp);
+ soup_state_load (state, fp);
+
+ fclose (fp);
+
+ return state;
+}
+
+int
+image_save (struct state *state, const char *filename)
+{
+ FILE *fp;
+
+ fp = fopen (filename, "w");
+ if (fp == 0) { perror (filename); return -1; }
+
+ global_state_save (state, fp);
+ cell_state_save (state, fp);
+ soup_state_save (state, fp);
+
+ fclose (fp);
+
+ return 0;
+}
+
+static void
+global_state_save (struct state *state, FILE *fp)
+{
+ int version = FILE_SAVE_VERSION;
+
+ fwrite (&version, sizeof version, 1, fp);
+ fwrite (&state->cell_cycle, sizeof state->cell_cycle, 1, fp);
+}
+
+static void
+global_state_load (struct state *state, FILE *fp)
+{
+ int version;
+
+ if (fread (&version, sizeof version, 1, fp) != 1)
+ {
+ fprintf (stderr, "error in global state\n");
+ abort ();
+ }
+ if (version != FILE_SAVE_VERSION)
+ {
+ fprintf (stderr, "soup image version numbers do not match\n");
+ abort ();
+ }
+
+ if (fread (&state->cell_cycle, sizeof state->cell_cycle, 1, fp) != 1)
+ {
+ fprintf (stderr, "error in global state\n");
+ abort ();
+ }
+
+ if (verbose) printf ("Total number of cycles executed so far: %LuB\n",
+ state->cell_cycle / 1000000000);
+}
--- /dev/null
+/* DLIFE Copyright (C) 2000 Richard W.M. Jones <rich@annexia.org>
+ * and other authors listed in the ``AUTHORS'' file.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id: image.h,v 1.1 2002/04/05 14:40:27 rich Exp $
+ */
+
+#ifndef image_h
+#define image_h
+
+#include "state.h"
+
+extern struct state *image_load (const char *filename, int _soup_size,
+ int thread_num);
+extern int image_save (struct state *state, const char *filename);
+
+#endif /* image_h */
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<!-- -*- html -*- -->
+<html>
+ <head>
+ <title>Distributed Artificial Life</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+ <h1 align="center">Distributed Artificial Life</h1>
+
+ <p>
+ DLIFE is a distributed version of <a
+ href="http://www.hip.atr.co.jp/~ray/">Tom S. Ray's</a> <a
+ href="http://www.hip.atr.co.jp/~ray/tierra/">Tierra</a>
+ artificial life program. Note that the machine language used is
+ similar to but not compatible with Tierra. Tom Ray talks about
+ his work (as far as I know, never completed) to create a <a
+ href="http://www.hip.atr.co.jp/~ray/pubs/reserves/">``Digital
+ Reserve''</a>. The DLIFE project is a development of this.
+ </p>
+
+ <p>
+ In other words, it's an alternative to the tedious process
+ of <a href="http://www.distributed.net/">cracking RC5 keys</a>
+ or <a href="http://setiathome.ssl.berkeley.edu/">searching
+ for aliens</a>. You've got a supercomputer on your desk,
+ let's go and create some life ...
+ </p>
+
+ <h2>News</h2>
+
+ <p><b>Fri Apr 5 23:03:27 BST 2002</b></p>
+
+ <p>
+ Version 1.0.0: Various fixes for Red Hat Linux 7.2.
+ </p>
+
+ <p><b>Mon Oct 16 23:11:13 BST 2000</b></p>
+
+ <p>
+ Version 0.0.16: Added another patch from Falk
+ Hueffner which improves the Debian package
+ handling.
+ </p>
+
+ <p><b>Sat Oct 14 15:44:27 BST 2000</b></p>
+
+ <p>
+ Version 0.0.15: Debian package (thanks to Falk Hueffner).
+ Client and soup processes now log status information to syslog.
+ </p>
+
+ <h2>Download</h2>
+
+ <p>
+ All software is distributed under the terms of the
+ <a href="files/COPYING">GNU General Public License (GPL)</a>.
+ </p>
+
+ <p>
+ The latest version is @VERSION@, released @RELEASEDATE@.
+ </p>
+
+ <table>
+ <tr>
+ <td> Source code for client and server </td>
+ <td> <a href="files/dlife-@VERSION@.tar.gz">dlife-@VERSION@.tar.gz</a> </td>
+ </tr>
+ <tr>
+ <td> Client: Binary RPM (for Red Hat, i686) </td>
+ <td> <a href="files/dlife-@VERSION@-1.i686.rpm">dlife-@VERSION@-1.i686.rpm</a> </td>
+ </tr>
+ <tr>
+ <td> Server: Binary RPM (for Red Hat, i686) </td>
+ <td> <a href="files/dlife-server-@VERSION@-1.i686.rpm">dlife-server-@VERSION@-1.i686.rpm</a> </td>
+ </tr>
+ <tr>
+ <td> Source RPM </td>
+ <td> <a href="files/dlife-@VERSION@-1.src.rpm">dlife-server-@VERSION@-1.src.rpm</a> </td>
+ </tr>
+ <tr>
+ <td> Perl RPMs </td>
+ <td> <a href="files/">Various Perl RPMs which you may require ...</a> </td>
+ </tr>
+ </table>
+
+ <p align="right"><a href="http://www.annexia.org/cgi-bin/autopatch.pl?dir=dlife">Patches from previous versions ...</a></p>
+ <p align="right"><a href="files/">Previous versions ...</a></p>
+
+ <h2>Documentation</h2>
+
+ <ul>
+ <li> <a href="machineref.html">DLIFE machine language reference</a> <br>
+ Documents the machine language implemented in the DLIFE
+ VM, the underlying philosophy, and how it differs from
+ the original Tierra machine language.
+ <li> <a href="archref.html">DLIFE distributed architecture reference</a>
+ <br>
+ Documents the distributed architecture of DLIFE, how
+ the VM runs, how cells get distributed between soups,
+ and how the C VM code and Perl network code interact.
+ </ul>
+
+ <hr>
+ <address><a href="mailto:rich@annexia.org">rich@annexia.org</a></address>
+<!-- Created: Fri Oct 6 14:35:11 BST 2000 -->
+<!-- hhmts start -->
+Last modified: Mon Oct 16 23:11:50 BST 2000
+<!-- hhmts end -->
+ </body>
+</html>
--- /dev/null
+/usr/share/automake-1.4/install-sh
\ No newline at end of file
--- /dev/null
+/* DLIFE Copyright (C) 2000 Richard W.M. Jones <rich@annexia.org>
+ * and other authors listed in the ``AUTHORS'' file.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id: load.c,v 1.2 2002/04/05 16:47:12 rich Exp $
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "types.h"
+#include "load.h"
+#include "cell.h"
+#include "soup.h"
+#include "state.h"
+
+struct cell *
+load_cell (struct state *state, const char *filename)
+{
+ FILE *fp;
+ int allocated = 0;
+ int len = 0;
+ char line[256];
+ byte_t *code = 0;
+ int n = 0, i, c = 0;
+ struct cell *cell;
+ struct soup_frag *frag;
+
+ fp = fopen (filename, "r");
+ if (fp == 0) { perror (filename); return 0; }
+
+ while (fgets (line, sizeof line, fp) != 0 && len < MAX_CELL_SIZE)
+ {
+ for (i = 0; i < strlen (line); ++i)
+ {
+ if (line[i] >= '0' && line[i] <= '9')
+ {
+ n *= 16;
+ n += line[i] - '0';
+ c++;
+ }
+ else if (line[i] >= 'a' && line[i] <= 'f')
+ {
+ n *= 16;
+ n += line[i] - 'a' + 10;
+ c++;
+ }
+ else if (line[i] >= 'A' && line[i] <= 'F')
+ {
+ n *= 16;
+ n += line[i] - 'A' + 10;
+ c++;
+ }
+ if (c == 2)
+ {
+ if (allocated - len <= 0)
+ {
+ code = realloc (code, allocated += 256);
+ if (code == 0) { perror ("realloc"); abort (); }
+ }
+ code[len++] = n;
+ n = c = 0;
+ }
+ }
+ }
+
+ if (c != 0)
+ {
+ fprintf (stderr, "%s: error in input file\n", filename);
+ fclose (fp);
+ free (code);
+ return 0;
+ }
+
+ fclose (fp);
+
+ /* Refuse any cells which are too small or too large. */
+ if (len < MIN_CELL_SIZE || len > MAX_CELL_SIZE)
+ {
+ fprintf (stderr, "%s: cell is too small or too large (len = %d)\n",
+ filename, len);
+ free (code);
+ return 0;
+ }
+
+ /* Allocate soup fragment. */
+ frag = soup_frag_malloc (state, 0, len);
+ if (frag == 0) { free (code); return 0; }
+
+ /* Allocate cell. */
+ cell = cell_malloc (state, 0, frag);
+ if (cell == 0) { free (code); return 0; }
+
+ /* Populate cell. */
+ for (i = 0; i < len; ++i)
+ set_soup (state, cell->frag, code[i], i);
+ free (code);
+
+ return cell;
+}
--- /dev/null
+/* DLIFE Copyright (C) 2000 Richard W.M. Jones <rich@annexia.org>
+ * and other authors listed in the ``AUTHORS'' file.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id: load.h,v 1.1 2002/04/05 14:40:27 rich Exp $
+ */
+
+#ifndef load_h
+#define load_h
+
+#include "config.h"
+#include "state.h"
+
+extern struct cell *load_cell (struct state *state, const char *filename);
+
+#endif /* load_h */
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+ <head>
+ <title>DLIFE machine language reference</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+ <h1>DLIFE machine language reference</h1>
+
+ <h2>General overview</h2>
+
+ <p>
+ I'm going to assume that you're mostly familiar
+ with <a href="http://www.hip.atr.co.jp/~ray/tierra/">Tierra</a>,
+ but I'll also give you a short introduction.
+ </p>
+
+ <p>
+ In DLIFE/Tierra, life forms consist of small
+ machine language programs called ``cells''.
+ Each cell has its own program counter and hence
+ its own thread of execution, and runs independently
+ of any other cell. Cells live in a virtual machine
+ (VM) called the ``soup''. The soup is just a big
+ piece of byte-addressed memory, 128 Kbytes in size
+ by default.
+ </p>
+
+ <p>
+ The soup contains an interpreter which interprets
+ the machine language. For DLIFE cells, the soup
+ is their entire universe. They cannot address or
+ access anything outside their own soup. (Although
+ they can occasionally jump from one soup to another
+ -- but more of that later).
+ </p>
+
+ <p>
+ All the cells sharing the soup are run timesliced
+ in a simple round-robin scheme, and hence each
+ cell will get roughly the same amount of actual CPU
+ dedicated to it.
+ </p>
+
+ <p>
+ The cell machine language is not 8086 assembler. In
+ fact, it's a special purpose machine language written
+ just to run cells. It has some similarities with
+ more traditional machine languages -- for example,
+ registers, indirect addressing, jumps, a stack,
+ and so on -- but also some strange features that
+ you wouldn't expect to find in a real machine
+ language. The most important feature of the
+ language is termed (in a term coined by Tom
+ Ray) its ``non-brittleness''. This means that
+ the language is robust against small corruptions,
+ changes, and the insertion or deletion of a few
+ bytes here and there. In a real machine language,
+ inserting a few bytes into a piece of code requires
+ that you relink the code so that all jump and call
+ target addresses change. If you didn't relink the code,
+ then the insertion would be fatal -- the code wouldn't
+ function at all. Real machine languages are said to
+ be ``brittle''. In the DLIFE machine language, insertions
+ and deletions are tolerated -- the code will continue to
+ work much as before. The main way in which this works
+ is that absolute addresses have been replaced by
+ explicit labels in the code:
+ </p>
+
+<pre>
+ code
+ : :
+ code
+ label 123
+ code
+ : : <---
+ code
+ jump to label 123
+ code
+ : :
+ code
+</pre>
+
+ <p>
+ Suppose in the example above that an accidental
+ insertion or deletion occurs at the point marked by the arrow.
+ The chances are that the code will continue to work,
+ because the ``jump'' command will still be able to
+ find and jump to the correct label.
+ </p>
+
+ <p>
+ Another important and unusual feature of the machine
+ language is that it allows cells to reproduce. Through
+ the use of the <tt>MALLOC</tt> and <tt>DIVIDE</tt>
+ instructions, a cell may produce a daughter cell,
+ populate it with code, and then divide (set it running
+ as an independent cell).
+ </p>
+
+ <p>
+ The soup interpreter is error-prone. Most instructions
+ will run as intended, but occasionally instructions
+ fail in certain ways. For example, an instruction to
+ increment the accumulator might, one in a hundred thousand times,
+ increment the accumulator <i>twice</i>, or even not at
+ all. The soup memory is also error-prone. So-called
+ cosmic rays hit the soup very occasionally, flipping
+ bits at random. By these means, cells may occasionally
+ mutate. Note that because the machine language is
+ very deliberately chosen to be non-brittle, mutations
+ often result in cells which still work, but perhaps
+ work in slightly different (better?) ways. Hence
+ cells evolve.
+ </p>
+
+ <p>
+ There is one initial cell, which was written by hand. This
+ cell is called the ``god cell'' (although perhaps Adam
+ or Eve might have been a better biblical parallel). This
+ cell simply copies itself repeatedly.
+ </p>
+
+ <p>
+ Cells which execute instructions incorrectly (for
+ example, they do not fill the accumulator register
+ with a suitable value before calling <tt>MALLOC</tt>)
+ accumulate errors. As the soup becomes more and more
+ full, a special process called the ``grim reaper''
+ is invoked. The grim reaper kills off the cells
+ with the largest error count until the soup pressure
+ is eased.
+ </p>
+
+ <p>
+ The DLIFE model is one of pure natural selection. There
+ are no artificial pressures placed on cells to become,
+ for example, good at executing some particular algorithm.
+ Instead, cells compete simply for space in the soup
+ and time on the virtual CPU.
+ </p>
+
+ <h2>Cell virtual machine</h2>
+
+ <p>
+ The cell VM consists of 4 registers, some local
+ storage, a stack and stack pointer, an error counter
+ and possibly an attached daughter cell.
+ </p>
+
+ <h3>Registers</h3>
+
+ <p>
+ The 4 visible registers are:
+ </p>
+
+ <table>
+ <tr>
+ <th> Register </th> <th> Purpose </th>
+ </tr>
+ <tr>
+ <td> A </td> <td> The accumulator, for mathematical
+ operations and general purpose use. </td>
+ </tr>
+ <tr>
+ <td> B </td> <td> Base address, for addressing local variables. </td>
+ </tr>
+ <tr>
+ <td> I </td> <td> Index address. </td>
+ </tr>
+ <tr>
+ <td> P </td> <td> Program counter. </td>
+ </tr>
+ </table>
+
+ <p>
+ All registers are 16 bit signed integers, storing
+ any value between -32768 and 32767 inclusive.
+ </p>
+
+ <p>
+ All addresses are stored relative to the start
+ address of the cell. Hence if P is set to zero,
+ then execution jumps to the beginning of the cell's
+ code.
+ </p>
+
+ <p>
+ When a cell is created, all registers are initialized
+ to zero.
+ </p>
+
+ <h3>Local storage</h3>
+
+ <p>
+ The cell has a fragment of soup memory. Because addresses
+ are relative, to the cell the memory appears to stretch from
+ address 0 to address N-1, where N is the total number
+ of bytes allocated to the cell by her mother's call
+ to <tt>MALLOC</tt>. It is not possible for
+ the cell to find out the value of N (we assume that
+ the mother allocated enough memory for the cell).
+ </p>
+
+ <p>
+ A cell may store code or data at any memory address
+ within itself. There is no distinction made in the
+ VM between code and data.
+ </p>
+
+ <p>
+ A cell may not write to memory outside the range 0 to N-1.
+ Doing so will incur an error. Cells may, however, read
+ any memory outside this range.
+ </p>
+
+ <p>
+ After calling <tt>MALLOC</tt>, the I register is
+ initialized with the start address of the daughter
+ cell. Between the <tt>MALLOC</tt> and the next call
+ to <tt>DIVIDE</tt>, the cell may additionally write
+ to addresses I through I + A - 1, in order to initialize
+ the daughter.
+ </p>
+
+ <h3>Stack</h3>
+
+ <p>
+ The cell has a stack of 16 words. Each stack entry is
+ a 16 bit signed integer.
+ </p>
+
+ <p>
+ A stack pointer stores the current position in the
+ stack.
+ </p>
+
+ <p>
+ The stack can only be accessed through one of the <tt>PUSH</tt>
+ or <tt>POP</tt> instructions. <tt>PUSH x</tt> (where ``x'' is
+ the name of a register) increments the value of the
+ stack pointer and copies the value in register x onto
+ the stack at the position addressed by the stack pointer.
+ <tt>POP x</tt> copies the value on the stack addressed
+ by the stack pointer into register x and decrements the
+ value of the stack pointer.
+ </p>
+
+ <p>
+ The stack is circular, in that pushing more than 16 numbers
+ onto the stack causes the stack to wrap around and overwrite
+ the top entry. Thus it is not possible to underflow or
+ overflow the stack.
+ </p>
+
+ <p>
+ The stack pointer register is not visible to the cell
+ VM. In other words, the cell cannot directly read or write
+ to the stack pointer (except implicitly through use of
+ the <tt>PUSH</tt> or <tt>POP</tt> instructions). Because
+ of this, it is not possible for the cell to tell if the
+ stack is implemented as grows-down or grows-up, nor
+ whether the implementation pushes first and changes the
+ stack pointer second or vice versa.
+ </p>
+
+ <p>
+ When the cell is created, all stack entries and the stack
+ pointer are initialized to zero.
+ </p>
+
+ <h3>Error counter</h3>
+
+ <p>
+ The error counter starts off at zero, and is incremented
+ by one every time the cell makes a mistake when
+ executing an instruction. Typical mistakes are:
+ </p>
+
+ <ul>
+ <li> Incorrectly initializing the A register before
+ calling <tt>MALLOC</tt>.
+ <li> Not calling <tt>MALLOC</tt> before calling <tt>DIVIDE</tt>.
+ <li> Not calling <tt>DIVIDE</tt> before calling <tt>MALLOC</tt>.
+ <li> Executing <tt>FINDF</tt> or <tt>FINDB</tt> and not
+ finding a matching label.
+ </ul>
+
+ <h2>Basic instruction set</h2>
+
+ <p>
+ The basic instruction set consists of just 17 commands
+ encoded in just 38 different numeric values.
+ </p>
+
+ <p>
+ Each instruction is encoded in a single byte.
+ </p>
+
+ <p>
+ Two instructions, <tt>FINDB</tt> and <tt>FINDF</tt>
+ might be considered to be multi-byte instructions.
+ See the description below for details.
+ </p>
+
+ <p>
+ There is one instruction prefix, <tt>IFZ</tt>, but
+ in the discussion below, we will just consider it
+ as if it was a single byte instruction (which, in
+ fact, it is).
+ </p>
+
+ <p>
+ The VM makes no distinction between code and data.
+ Any byte which is addressable as part of the mother
+ cell can be considered to be either executable
+ code or a data byte (or both).
+ </p>
+
+ <p>
+ Instructions are encoded into soup bytes as follows:
+ </p>
+
+<pre>
+ Most Least
+ significant significant
+ bit bit
++----+----+----+----+----+----+----+----+
+| | | | | | | | |
+| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+| | | | | | | | |
++----+----+----+----+----+----+----+----+
+ \_______/ \___________________________/
+ | |
+ Ignored Instruction encoding
+ (values 0-4,7-39 correspond to
+ instructions, values 40-63
+ are unknown and result in
+ cell errors)
+</pre>
+
+ <p>
+ The lower 6 bits are interpreted as follows:
+ </p>
+
+ <table border=1>
+ <tr>
+ <th> Dec </th>
+ <th> Hex </th>
+ <th> Bin </th>
+ <th> Mnemonic </th>
+ <th> Meaning </th>
+ </tr>
+ <tr>
+ <td> 0 </td> <td> 00 </td> <td> 00 0000 </td>
+ <td> <tt>NOP0</tt> </td>
+ <td> No-op. This instruction does nothing when executed
+ but is used as a pattern matching label by <tt>FINDB</tt>
+ and <tt>FINDF</tt>. </td>
+ </tr>
+ <tr>
+ <td> 1 </td> <td> 01 </td> <td> 00 0001 </td>
+ <td> <tt>NOP1</tt> </td>
+ <td> No-op. This instruction does nothing when executed
+ but is used as a pattern matching label by <tt>FINDB</tt>
+ and <tt>FINDF</tt>. </td>
+ </tr>
+ <tr>
+ <td> 2 </td> <td> 02 </td> <td> 00 0010 </td>
+ <td> <tt>INC A</tt> </td>
+ <td> A <- A + 1 </td>
+ </tr>
+ <tr>
+ <td> 3 </td> <td> 03 </td> <td> 00 0011 </td>
+ <td> <tt>DEC A</tt> </td>
+ <td> A <- A - 1 </td>
+ </tr>
+ <tr>
+ <td> 4 </td> <td> 04 </td> <td> 00 0100 </td>
+ <td> <tt>SHL A</tt> </td>
+ <td> A <- A << 1 </td>
+ </tr>
+ <tr>
+ <td> 7 </td> <td> 07 </td> <td> 00 0111 </td>
+ <td> <tt>IFZ</tt> </td>
+ <td> <tt>IFZ</tt> is normally used as an instruction
+ prefix, ie. <tt>IFZ</tt> <instruction>.
+ If A == 0, execute the next instruction,
+ otherwise skip the next instruction. </td>
+ </tr>
+ <tr>
+ <td> 8 </td> <td> 08 </td> <td> 00 1000 </td>
+ <td> <tt>FINDB</tt> </td>
+ <td> <tt>FINDB</tt> should be followed by a pattern
+ (a series of one or more NOP0 and NOP1 bytes). The
+ <tt>FINDB</tt> instruction searches backwards
+ from the current program counter until it finds
+ the <tt>inverse</tt> pattern of NOP0 and NOP1 bytes.
+ It returns the relative address of the found pattern
+ in register I. If the pattern is not found, it
+ sets I == 0.
+ </td>
+ </tr>
+ <tr>
+ <td> 9 </td> <td> 09 </td> <td> 00 1001 </td>
+ <td> <tt>FINDF</tt> </td>
+ <td> <tt>FINDF</tt> should be followed by a pattern
+ (a series of one or more NOP0 and NOP1 bytes). The
+ <tt>FINDF</tt> instruction searches forwards
+ from the current program counter until it finds
+ the <tt>inverse</tt> pattern of NOP0 and NOP1 bytes.
+ It returns the relative address of the found pattern
+ in register I. If the pattern is not found, it
+ sets I <- 0.
+ </td>
+ </tr>
+ <tr>
+ <td> 10 </td> <td> 0A </td> <td> 00 1010 </td>
+ <td> <tt>MALLOC</tt> </td>
+ <td> <tt>MALLOC</tt> allocates a daughter
+ cell of size A bytes. It returns the address
+ of the daughter cell in register I, or if the
+ memory could not be allocated, it sets I <- 0.
+ Only one daughter cell may be allocated at a
+ time. Therefore, calling <tt>MALLOC</tt> twice
+ without calling <tt>DIVIDE</tt> in between is an
+ error. Register A must be between 10 and 512.
+ </td>
+ </tr>
+ <tr>
+ <td> 11 </td> <td> 0B </td> <td> 00 1011 </td>
+ <td> <tt>DIVIDE</tt> </td>
+ <td> <tt>DIVIDE</tt> splits off the current daughter
+ cell and starts it running as a fully independent
+ cell. The daughter cell must first have been allocated
+ by <tt>MALLOC</tt> and populated with code, so
+ calling <tt>DIVIDE</tt> twice without calling
+ <tt>MALLOC</tt> in between is an error.
+ </td>
+ </tr>
+ <tr>
+ <td> 12 </td> <td> 0C </td> <td> 00 1100 </td>
+ <td> <tt>MOVE [I],A</tt> </td>
+ <td> Load the unsigned byte at relative address I into
+ register A.
+ </td>
+ </tr>
+ <tr>
+ <td> 13 </td> <td> 0D </td> <td> 00 1101 </td>
+ <td> <tt>MOVE A,[I]</tt> </td>
+ <td> Store the value of register A in the soup byte
+ at relative address I. If A is less than 0 or
+ greater than 255 then the effects are undefined.
+ If I lies outside the boundaries of the mother
+ or daughter cells, then this is a cell error.
+ </td>
+ </tr>
+ <tr>
+ <td> 14 </td> <td> 0E </td> <td> 00 1110 </td>
+ <td> <tt>DMOVE [I],A</tt> </td>
+ <td> Load the signed word (two bytes) at relative address I
+ into register A. The VM is big endian (Motorola ordering).
+ </td>
+ </tr>
+ <tr>
+ <td> 15 </td> <td> 0F </td> <td> 00 1111 </td>
+ <td> <tt>DMOVE A,[I]</tt> </td>
+ <td> Store the value of register A in the soup
+ bytes at relative address I and I+1. If (I, I+1)
+ lies outside the boundaries of the mother or
+ daughter cells, then this is a cell error.
+ The VM is big endian (Motorola ordering).
+ </td>
+ </tr>
+ <tr>
+ <td> 16-31 </td> <td> 10-1F </td> <td> 01 r2r1 </td>
+ <td> <tt>XOR <reg1>,<reg2> </tt> </td>
+ <td> <reg2> <- <reg1> XOR <reg2>
+ for any registers in A (00), B (01), I (10) or P (11).
+ </td>
+ </tr>
+ <tr>
+ <td> 32-35 </td> <td> 20-23 </td> <td> 10 00rr </td>
+ <td> <tt>PUSH <reg> </tt> </td>
+ <td> Push the register onto the stack for any
+ registers in A (00), B (01), I (10) or P (11).
+ </td>
+ </tr>
+ <tr>
+ <td> 36-39 </td> <td> 24-27 </td> <td> 10 01rr </td>
+ <td> <tt>POP <reg> </tt> </td>
+ <td> Pop the top of the stack into the register for
+ any registers in A (00), B (01), I (10) or P (11).
+ </td>
+ </tr>
+ </table>
+
+ <p>
+ Note that instruction encodings 5, 6 and 40-63 are
+ not used. Attempting to execute one of these unknown
+ instructions results in a cell error.
+ </p>
+
+ <h2>Instruction set timings</h2>
+
+ <p>
+ This table shows the number of (virtual) CPU cycles
+ taken to execute each instruction.
+ </p>
+
+ <table border=1>
+ <tr>
+ <th> Instruction </th>
+ <th> Cycles </th>
+ <th> Notes </th>
+ </tr>
+ <tr> <td> <tt>NOP0</tt> </td> <td> 1 </td> </tr>
+ <tr> <td> <tt>NOP1</tt> </td> <td> 1 </td> </tr>
+ <tr> <td> <tt>INC A</tt> </td> <td> 1 </td> </tr>
+ <tr> <td> <tt>DEC A</tt> </td> <td> 1 </td> </tr>
+ <tr> <td> <tt>SHL A</tt> </td> <td> 1 </td> </tr>
+ <tr> <td> <tt>IFZ</tt> </td> <td> 1 </td> </tr>
+ <tr> <td> <tt>FINDB</tt> </td> <td> 1 + n </td>
+ <td> ``n'' is the distance between the current
+ program counter and the start of the matched
+ pattern. </td>
+ </tr>
+ <tr> <td> <tt>FINDF</tt> </td> <td> 1 + n</td>
+ <td> ``n'' is the distance between the current
+ program counter and the start of the matched
+ pattern. </td>
+ </tr>
+ <tr> <td> <tt>MALLOC</tt> </td> <td> 1 </td> </tr>
+ <tr> <td> <tt>DIVIDE</tt> </td> <td> 1 </td> </tr>
+ <tr> <td> <tt>MOVE [I],A</tt> </td> <td> 1 </td> </tr>
+ <tr> <td> <tt>MOVE A,[I]</tt> </td> <td> 1 </td> </tr>
+ <tr> <td> <tt>DMOVE [I],A</tt> </td> <td> 1 </td> </tr>
+ <tr> <td> <tt>DMOVE A,[I]</tt> </td> <td> 1 </td> </tr>
+ <tr> <td> <tt>XOR <reg1>,<reg2></tt> </td> <td> 1 </td> </tr>
+ <tr> <td> <tt>PUSH <reg></tt> </td> <td> 1 </td> </tr>
+ <tr> <td> <tt>POP <reg></tt> </td> <td> 1 </td> </tr>
+ </table>
+
+ <h2>Instruction set macros</h2>
+
+ <p>
+ The basic instruction set is augmented with macros
+ which allow common programming paradigms to be
+ written. Macros are just a short-hand used in
+ the assembler / disassembler, and are not implemented
+ in any way by the VM.
+ </p>
+
+ <table border=1>
+ <tr>
+ <th> Macro </th>
+ <th> Expands to </th>
+ <th> Meaning </th>
+ <th> Side effects? </th>
+ </tr>
+ <tr>
+ <th colspan=4> Basic register operations ... </th>
+ </tr>
+ <tr>
+ <td> <tt>MOVE <reg1>,<reg2></tt> </td>
+ <td> <tt>PUSH <reg1><br>POP <reg2></tt> </td>
+ <td> Move the contents of register 1 into register 2. </td>
+ <td> None. </td>
+ </tr>
+ <tr>
+ <td> <tt>SWAP <reg1>,<reg2></tt> </td>
+ <td> <tt>XOR <reg1>,<reg2><br>
+ XOR <reg2>,<reg1><br>
+ XOR <reg1>,<reg2><br>
+ XOR <reg2>,<reg1></tt> </td>
+ <td> This has the effect of swapping the contents of
+ registers 1 and 2. </td>
+ <td> None. </td>
+ </tr>
+ <tr>
+ <td> <tt>ZERO <reg></tt> </td>
+ <td> <tt>XOR <reg>,<reg></tt> </td>
+ <td> A <- 0 </td>
+ <td> None. </td>
+ </tr>
+ <tr>
+ <td> <tt>ADD <n>, A</tt> </td>
+ <td> <tt>INC A</tt> repeated n times. This is only
+ really suitable for small values of n. </td>
+ <td> A <- A + n </td>
+ <td> None. </td>
+ </tr>
+ <tr>
+ <td> <tt>MOVE <n>, A</tt> </td>
+ <td> <tt>ZERO A</tt> followed by a series of
+ <tt>SHL A</tt> and <tt>INC A</tt> operations
+ required to initialize A to n. (n >= 0) </td>
+ <td> A <- n </td>
+ <td> None. </td>
+ </tr>
+ <tr>
+ <th colspan=4> Access local (word-sized) variables, relative
+ to the base address register B ... </th>
+ </tr>
+ <tr>
+ <td> <tt>LOAD <n>, A</tt> </td>
+ <td> <tt>PUSH I<br>MOVE B,A<br>ADD n*2,A<br>MOVE A,I<br>
+ DMOVE [I],A<br>POP I</tt> </td>
+ <td> Load variable number n into register A. </td>
+ <td> Destroys contents of I register. </td>
+ </tr>
+ <tr>
+ <td> <tt>STORE A,<n></tt> </td>
+ <td> <tt>PUSH I<br>PUSH A<br>MOVE B,A<br>ADD n*2,A<br>MOVE A,I<br>
+ POP A<br>DMOVE A,[I]<br>POP I</tt> </td>
+ <td> Store register A in variable number n. </td>
+ <td> Destroys contents of I register. </td>
+ </tr>
+ <tr>
+ <th colspan=4> Jumps and subroutines ... </th>
+ </tr>
+ <tr>
+ <td> <tt>JMP I</tt> </td>
+ <td> <tt>PUSH I<br>POP P</tt> </td>
+ <td> Jump to address I. </td>
+ <td> None. </td>
+ </tr>
+ <tr>
+ <td> <tt>JMPF <pattern></tt> </td>
+ <td> <tt>FINDF <pattern><br>PUSH I<br>POP P</tt> </td>
+ <td> Jump forwards to pattern. </td>
+ <td> Destroys contents of I register. </td>
+ </tr>
+ <tr>
+ <td> <tt>JMPB <pattern></tt> </td>
+ <td> <tt>FINDB <pattern><br>PUSH I<br>POP P</tt> </td>
+ <td> Jump backwards to pattern. </td>
+ <td> Destroys contents of I register. </td>
+ </tr>
+ <tr>
+ <td> <tt>JMPZF <pattern></tt> </td>
+ <td> <tt>FINDF <pattern><br>PUSH I<br>IFZ POP P<br>
+ POP I</tt> </td>
+ <td> If A == 0, jump forwards to pattern. </td>
+ <td> Destroys contents of I register. </td>
+ </tr>
+ <tr>
+ <td> <tt>JMPZB <pattern></tt> </td>
+ <td> <tt>FINDB <pattern><br>PUSH I<br>IFZ POP P<br>
+ POP I</tt> </td>
+ <td> If A == 0, jump backwards to pattern. </td>
+ <td> Destroys contents of I register. </td>
+ </tr>
+ <tr>
+ <td> <tt>CALLF <pattern></tt> </td>
+ <td> <tt>PUSH P<br>FINDF <pattern><br>PUSH I<br>POP P</tt> </td>
+ <td> Call forwards to a subroutine at pattern. The current
+ address is saved on the stack. </td>
+ <td> Destroys contents of I register. </td>
+ </tr>
+ <tr>
+ <td> <tt>CALLB <pattern></tt> </td>
+ <td> <tt>PUSH P<br>FINDB <pattern><br>PUSH I<br>POP P</tt> </td>
+ <td> Call backwards to a subroutine at pattern. The current
+ address is saved on the stack. </td>
+ <td> Destroys contents of I register. </td>
+ </tr>
+ <tr>
+ <td> <tt>RET <n></tt> </td>
+ <td> <tt>POP A<br>ADD n+3,A<br>MOVE A,P</tt> </td>
+ <td> Return from subroutine. n is the length of the
+ pattern in the corresponding <tt>CALLF</tt>/<tt>CALLB</tt>
+ instruction. The return address should be the top
+ address on the stack. </td>
+ <td> Destroys contents of A register. </td>
+ </tr>
+ <tr>
+ <th colspan=4> Assembler directives ... </th>
+ </tr>
+ <tr>
+ <td> <tt>DB <n></tt> </td>
+ <td> </td>
+ <td> Define n bytes of scratch space. The scratch
+ space is initialized with 0xFF bytes (<strong>not</strong>
+ with zero bytes, since those clash with pattern symbols). </td>
+ <td> None. </td>
+ </tr>
+ </table>
+
+ <h2>Patterns</h2>
+
+ <p>
+ The assembler recognizes patterns and writes out
+ a series of <tt>NOP0</tt> and <tt>NOP1</tt> bytes.
+ </p>
+
+ <table border=1>
+ <tr>
+ <th> Mnemonic </th> <th> Expands to </th>
+ </tr>
+ <tr>
+ <td> <tt><pattern>:</tt> </td>
+ <td> Each 0 and 1 in the pattern is translated into
+ a NOP0 and NOP1 on output. </td>
+ </tr>
+ <tr>
+ <td> <tt>~<pattern>:</tt> </td>
+ <td> Each 0 and 1 in the pattern is translated into
+ a NOP1 and NOP0 on output (note the inversion). </td>
+ </tr>
+ <tr>
+ <td> instruction <tt><pattern>:</tt> </td>
+ <td> Each 0 and 1 in the pattern is translated into
+ a NOP0 and NOP1 on output. </td>
+ </tr>
+ <tr>
+ <td> instruction <tt>~<pattern>:</tt> </td>
+ <td> Each 0 and 1 in the pattern is translated into
+ a NOP1 and NOP0 on output (note the inversion). </td>
+ </tr>
+ </table>
+
+ <p>
+ Since the <tt>FINDB</tt> and <tt>FINDF</tt> patterns
+ search for the <i>inverse</i> of a pattern, a typical
+ instruction sequence will look like this:
+ </p>
+
+<pre>
+0011:
+ ; : :
+ ; : :
+
+ FINDB ~0011
+ ; I contains address of 0011 pattern.
+</pre>
+
+ <hr>
+ <address><a href="mailto:rich@annexia.org">Richard Jones</a></address>
+<!-- Created: Sat Oct 7 10:09:40 BST 2000 -->
+<!-- hhmts start -->
+Last modified: Sat Oct 7 13:49:42 BST 2000
+<!-- hhmts end -->
+ </body>
+</html>
--- /dev/null
+/* DLIFE Copyright (C) 2000 Richard W.M. Jones <rich@annexia.org>
+ * and other authors listed in the ``AUTHORS'' file.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id: main.c,v 1.3 2002/12/11 17:16:21 rich Exp $
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+
+#ifdef HAVE_GRP_H
+#include <grp.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
+
+#include "cell.h"
+#include "soup.h"
+#include "load.h"
+#include "params.h"
+#include "random.h"
+#include "state.h"
+#include "image.h"
+
+unsigned soup_fetch_failure = 1000000;
+unsigned inc_pc_failure = 1000000;
+unsigned insn_exec_failure = 1000000;
+unsigned access_control_failure = 10;
+unsigned cell_initialization_failure = 1000000;
+int reaper_invoke_threshold = 80;
+int reaper_reap_threshold = 79;
+int save_period = 5;
+int outgoing_period = 10;
+int incoming_period = 60;
+int info_period = 60;
+int max_cells_incoming_per_pass = 4;
+
+int verbose = 0;
+
+static int soup_size = 128*1024; /* Read from configuration file. */
+
+static const char *conf_file = CONFDIR "/soup.conf";
+static const char *save_dir = SPOOLDIR;
+
+static void parse_args (int argc, char *argv[]);
+static void read_config_file (void);
+static int detect_nr_cpus (void);
+
+int
+main (int argc, char *argv[])
+{
+ char filename[256];
+ int nr_cpus, i;
+
+ /* Parse the command line. */
+ parse_args (argc, argv);
+
+ /* Read the configuration file. */
+ read_config_file ();
+
+ /* Initialize stuff. */
+ random_init ();
+
+#ifdef HAVE_OPENLOG
+ /* Open connection to syslog. */
+ openlog ("dlife_soup", LOG_PID, LOG_DAEMON);
+#endif
+
+ /* Find out how many processors are available. */
+ nr_cpus = detect_nr_cpus ();
+
+ /* Find existing saves directory. If there is a soup image in there,
+ * then we will load it. Otherwise we will start with the god cell.
+ */
+ if (chdir (save_dir) < 0)
+ {
+ perror (save_dir);
+ exit (1);
+ }
+
+#ifdef HAVE_NICE
+ /* Reduce our priority down to the minimum. */
+ nice (64);
+#endif
+
+#if defined(HAVE_GETUID) && defined(HAVE_SETUID) && defined(HAVE_SETGID) && defined(HAVE_GETPWNAM) && defined(HAVE_INITGROUPS)
+ /* If we are running as root, change to user dlife. */
+ if (getuid () == 0)
+ {
+ struct passwd *pw = getpwnam ("dlife");
+
+ if (pw)
+ {
+ initgroups ("dlife", pw->pw_gid);
+ setgid (pw->pw_gid);
+ setuid (pw->pw_uid);
+ }
+ else
+ {
+ fprintf (stderr, "cannot change to user/group dlife");
+ }
+ }
+#endif
+
+#ifdef HAVE_SYSLOG
+ syslog (LOG_INFO,
+ "version " VERSION " starting [conf="
+ CONFDIR ", spool=" SPOOLDIR ", cpus=%d]", nr_cpus);
+#endif
+
+ /* Fork once for each processor. */
+ for (i = 0; i < nr_cpus; ++i)
+ {
+ int pid;
+
+ pid = fork ();
+ if (pid < 0)
+ {
+ perror ("fork");
+ abort ();
+ }
+
+ if (pid == 0)
+ {
+ /* This is the child process. */
+ struct state *cpu_state;
+
+ /* Try to load the previous soup image. If the soup image
+ * cannot be found, then instead load the god cell.
+ */
+ sprintf (filename, "saved/soup%d.img", i);
+
+ cpu_state = image_load (filename, soup_size, i);
+
+ if (cpu_state)
+ {
+ if (verbose)
+ printf ("CPU %d: starting from previous image file.\n", i);
+ }
+ else
+ {
+ struct cell *god;
+
+ if (verbose)
+ printf ("CPU %d: no soup image found, loading god cell\n", i);
+
+ cpu_state = state_malloc (soup_size, i);
+
+ if ((god = load_cell (cpu_state, "god.dlo")) == 0)
+ {
+ fprintf (stderr, "dlife_soup: cannot load god cell god.dlo\n");
+#ifdef HAVE_SYSLOG
+ syslog (LOG_ERR,
+ "cannot load god cell " SPOOLDIR
+ "/god.dlo -- exiting");
+#endif
+ abort ();
+ }
+ cell_activate (cpu_state, god);
+ }
+
+ cpu_state->filename = strdup (filename);
+
+ /* Detach from the terminal. */
+ close (0);
+ close (1);
+ close (2);
+ setsid ();
+
+ /* Start running. */
+ run_thread (cpu_state);
+
+ exit (0);
+ }
+ }
+
+ /* Parent process exits. The children will automatically be
+ * cleaned up by init(8).
+ */
+ exit (0);
+}
+
+/* Parse the command line arguments. */
+static void
+parse_args (int argc, char *argv[])
+{
+ int c;
+
+ while ((c = getopt (argc, argv, "f:r:v")) != -1)
+ {
+ switch (c)
+ {
+ case 'f':
+ conf_file = optarg;
+ break;
+ case 'r':
+ save_dir = optarg;
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ default:
+ fprintf (stderr,
+ "usage: dlife_soup [-f conf-file] [-r save-dir] [-v]\n");
+ exit (1);
+ }
+ }
+}
+
+/* Return true if n is a power of 2. */
+static int
+is_power_2 (int n)
+{
+ while ((n & 1) == 0)
+ n >>= 1;
+ return n == 1;
+}
+
+static void
+read_config_file (void)
+{
+ FILE *fp;
+ char buffer[256], *t;
+
+ fp = fopen (conf_file, "r");
+ if (fp == 0)
+ {
+ if (verbose) printf ("No configuration file found.\n");
+ return;
+ }
+
+ while (fgets (buffer, sizeof buffer, fp) != 0)
+ {
+ /* Remove trailing \n and \r. */
+ t = buffer + strlen (buffer) - 1;
+ while (t >= buffer && (*t == '\n' || *t == '\r'))
+ *t-- = '\0';
+
+ /* Remove any comments (after a ``#'' character). */
+ t = strchr (buffer, '#');
+ if (t)
+ *t = '\0';
+
+ /* Look for lines which we understand. */
+ if (sscanf (buffer, "soup_fetch_failure %u", &soup_fetch_failure) == 1)
+ {
+ /* No checks required. */
+ continue;
+ }
+ if (sscanf (buffer, "inc_pc_failure %u", &inc_pc_failure) == 1)
+ {
+ /* No checks required. */
+ continue;
+ }
+ if (sscanf (buffer, "insn_exec_failure %u", &insn_exec_failure) == 1)
+ {
+ /* No checks required. */
+ continue;
+ }
+ if (sscanf (buffer, "access_control_failure %u", &access_control_failure) == 1)
+ {
+ /* No checks required. */
+ continue;
+ }
+ if (sscanf (buffer, "cell_initialization_failure %u", &cell_initialization_failure) == 1)
+ {
+ /* No checks required. */
+ continue;
+ }
+ if (sscanf (buffer, "reaper_invoke_threshold %d", &reaper_invoke_threshold) == 1)
+ {
+ if (reaper_invoke_threshold < 0 || reaper_invoke_threshold > 100)
+ {
+ fprintf (stderr, "reaper_invoke_threshold is a percentage: it must be 0 - 100\n");
+ exit (1);
+ }
+ continue;
+ }
+ if (sscanf (buffer, "reaper_reap_threshold %d", &reaper_reap_threshold) == 1)
+ {
+ if (reaper_reap_threshold < 0 || reaper_reap_threshold > 100)
+ {
+ fprintf (stderr, "reaper_reap_threshold is a percentage: it must be 0 - 100\n");
+ exit (1);
+ }
+ continue;
+ }
+ if (sscanf (buffer, "soup_size %d", &soup_size) == 1)
+ {
+ if (soup_size <= 0 || ! is_power_2 (soup_size))
+ {
+ fprintf (stderr, "soup_size must be a power of 2\n");
+ exit (1);
+ }
+ continue;
+ }
+ if (sscanf (buffer, "save_period %d", &save_period) == 1)
+ {
+ /* No checks required. */
+ continue;
+ }
+ if (sscanf (buffer, "outgoing_period %d", &outgoing_period) == 1)
+ {
+ /* No checks required. */
+ continue;
+ }
+ if (sscanf (buffer, "incoming_period %d", &incoming_period) == 1)
+ {
+ /* No checks required. */
+ continue;
+ }
+ if (sscanf (buffer, "info_period %d", &info_period) == 1)
+ {
+ /* No checks required. */
+ continue;
+ }
+ }
+}
+
+/* Detect the number of CPUs available. This is very operating system
+ * specific.
+ */
+
+#ifdef linux
+
+#ifdef __alpha__
+
+static int
+detect_nr_cpus ()
+{
+ FILE *fp;
+ int n = -1;
+ char line[256];
+
+ fp = fopen ("/proc/cpuinfo", "r");
+ if (fp == 0)
+ {
+ perror ("/proc/cpuinfo");
+ fprintf (stderr, "warning: cannot detect number of CPUs available\n");
+ return 1;
+ }
+
+ while (fgets (line, sizeof line, fp))
+ {
+ if (sscanf (line, "cpus detected : %d", &n) == 1)
+ break;
+ }
+
+ fclose (fp);
+
+ if (verbose)
+ printf ("number of CPUs detected: %d\n", n);
+
+ if (n <= 0)
+ {
+ fprintf (stderr, "warning: cannot detect number of CPUs available\n");
+ return 1;
+ }
+
+ return n;
+}
+
+#elif __sparc__
+
+static int
+detect_nr_cpus ()
+{
+ FILE *fp;
+ int n = -1;
+ char line[256];
+
+ fp = fopen ("/proc/cpuinfo", "r");
+ if (fp == 0)
+ {
+ perror ("/proc/cpuinfo");
+ fprintf (stderr, "warning: cannot detect number of CPUs available\n");
+ return 1;
+ }
+
+ while (fgets (line, sizeof line, fp))
+ {
+ if (sscanf (line, "ncpus active : %d", &n) == 1)
+ break;
+ }
+
+ fclose (fp);
+
+ if (verbose)
+ printf ("number of CPUs detected: %d\n", n);
+
+ if (n <= 0)
+ {
+ fprintf (stderr, "warning: cannot detect number of CPUs available\n");
+ return 1;
+ }
+
+ return n;
+}
+
+#else /* !__alpha__ || __sparc__ */
+
+static int
+detect_nr_cpus ()
+{
+ FILE *fp;
+ int n, c = 0;
+ char line[256];
+
+ fp = fopen ("/proc/cpuinfo", "r");
+ if (fp == 0)
+ {
+ perror ("/proc/cpuinfo");
+ fprintf (stderr, "warning: cannot detect number of CPUs available\n");
+ return 1;
+ }
+
+ while (fgets (line, sizeof line, fp))
+ {
+ if (sscanf (line, "processor : %d", &n) == 1 && n+1 > c)
+ {
+ c = n+1;
+ }
+ }
+
+ fclose (fp);
+
+ if (verbose)
+ printf ("number of CPUs detected: %d\n", c);
+
+ if (c <= 0)
+ {
+ fprintf (stderr, "warning: cannot detect number of CPUs available\n");
+ return 1;
+ }
+
+ return c;
+}
+
+#endif /* !__alpha__ */
+
+#else /* !linux */
+
+static void
+detect_nr_cpus ()
+{
+ fprintf (stderr, "warning: cannot detect number of CPUs available on this platform\n");
+ return 1;
+}
+
+#endif
--- /dev/null
+/usr/share/automake-1.4/missing
\ No newline at end of file
--- /dev/null
+/usr/share/automake-1.4/mkinstalldirs
\ No newline at end of file
--- /dev/null
+/* DLIFE Copyright (C) 2000 Richard W.M. Jones <rich@annexia.org>
+ * and other authors listed in the ``AUTHORS'' file.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id: params.h,v 1.1 2002/04/05 14:40:27 rich Exp $
+ */
+
+#ifndef params_h
+#define params_h
+
+#include "config.h"
+
+/* Probabilities. (ie. 1 in N). */
+extern unsigned soup_fetch_failure;
+extern unsigned inc_pc_failure;
+extern unsigned insn_exec_failure;
+extern unsigned access_control_failure;
+extern unsigned cell_initialization_failure;
+
+/* Percentages. (0-100). */
+extern int reaper_invoke_threshold;
+extern int reaper_reap_threshold;
+
+/* Save / load parameters. */
+extern int save_period;
+extern int outgoing_period;
+extern int incoming_period;
+extern int info_period;
+extern int max_cells_incoming_per_pass;
+
+#endif /* params_h */
--- /dev/null
+/* DLIFE Copyright (C) 2000 Richard W.M. Jones <rich@annexia.org>
+ * and other authors listed in the ``AUTHORS'' file.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id: random.c,v 1.1 2002/04/05 14:40:27 rich Exp $
+ */
+
+/* This module should generate high quality random numbers. It
+ * doesn't at the moment, but hopefully someone should be able to
+ * fix that. XXX
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
+#include "types.h"
+#include "random.h"
+
+void
+random_init ()
+{
+#if PERFECT_CPU
+ fprintf (stderr, "warning: PERFECT_CPU is defined in <random.h>\n");
+#endif
+
+ srandom (time (NULL));
+}
--- /dev/null
+/* DLIFE Copyright (C) 2000 Richard W.M. Jones <rich@annexia.org>
+ * and other authors listed in the ``AUTHORS'' file.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id: random.h,v 1.1 2002/04/05 14:40:28 rich Exp $
+ */
+
+#ifndef random_h
+#define random_h
+
+#include "config.h"
+
+#include <stdlib.h>
+
+extern void random_init (void);
+
+/* Define this to run on a fault-free ``perfect'' CPU. (Use this
+ * only when debugging).
+ */
+#define PERFECT_CPU 0
+
+/* Return true 1 in PROBABILITY times. The argument PROBABILITY
+ * is not limited to just powers of 2, but it must be an integer.
+ */
+extern inline int
+chance (unsigned probability)
+{
+#if !PERFECT_CPU
+ return ((unsigned)random() % probability) == 0;
+#else
+ return 0;
+#endif
+}
+
+/* Return 32 bits of randomness. */
+extern inline unsigned
+get_rand_int ()
+{
+ return (unsigned)random();
+}
+
+/* Return 16 bits of randomness. */
+extern inline unsigned
+get_rand_short ()
+{
+ return (unsigned)random() & 0xffff;
+}
+
+/* Return 8 bits of randomness. */
+extern inline unsigned
+get_rand_byte ()
+{
+ return (unsigned)random() & 0xff;
+}
+
+#endif /* random_h */
--- /dev/null
+# Copy of servers.txt.
+
+server dlife.annexia.org eu uk
--- /dev/null
+/* DLIFE Copyright (C) 2000 Richard W.M. Jones <rich@annexia.org>
+ * and other authors listed in the ``AUTHORS'' file.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id: soup.c,v 1.2 2002/04/05 16:47:13 rich Exp $
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_ASSERT_H
+#include <assert.h>
+#endif
+
+#include "types.h"
+#include "soup.h"
+#include "cell.h"
+#include "random.h"
+#include "state.h"
+#include "crc.h"
+
+#define TRACE_SOUP_ALLOCATIONS 0
+
+void
+soup_init (struct state *state, int _soup_size)
+{
+ int i;
+
+ state->soup_size = _soup_size;
+ state->soup_free = _soup_size;
+ state->soup = malloc (_soup_size);
+ if (state->soup == 0) { perror ("malloc"); abort (); }
+
+ /* Fill the soup with entropy. */
+ for (i = 0; i < _soup_size; ++i)
+ {
+ state->soup[i] = get_rand_byte ();
+ }
+}
+
+/* Allocate a new fragment of soup. */
+struct soup_frag *
+soup_frag_malloc (struct state *state,
+ struct soup_frag *mother_frag, reg_t len)
+{
+ struct soup_frag *p, *t;
+ int offset;
+ int is_first_cell = state->soup_free == state->soup_size;
+
+#if TRACE_SOUP_ALLOCATIONS
+ printf ("soup alloc: want %d bytes ", len);
+#endif
+
+ p = malloc (sizeof (struct soup_frag));
+ if (p == 0) { perror ("malloc"); abort (); }
+
+ /* Common fields. */
+ p->len = len;
+ state->soup_free -= len;
+
+ /* The first cell is allocated specially. */
+ if (is_first_cell)
+ {
+ p->next = p;
+ p->prev = p;
+ p->base = 0;
+
+#if TRACE_SOUP_ALLOCATIONS
+ printf ("first cell 0 OK\n");
+#endif
+
+ return p;
+ }
+
+ /* If a cell has no parent, we can insert it anywhere. */
+ if (mother_frag == 0)
+ {
+ /* Need to go and grab a cell at random, then search indefinitely
+ * for a free space.
+ */
+ mother_frag = _cell_get_any_frag (state);
+ t = mother_frag;
+ offset = 0;
+
+ do
+ {
+ int diff;
+
+#if TRACE_SOUP_ALLOCATIONS
+ printf ("[%d,%d:%d,%d] ",
+ t->base, t->base + t->len,
+ t->next->base, t->next->base + t->next->len);
+#endif
+
+ /* Handle the wrap-around case gracefully. */
+ if (t->next->base > t->base)
+ diff = t->next->base - (t->base + t->len);
+ else
+ diff = t->next->base - (t->base + t->len) + state->soup_size;
+
+ /* Is there space after this fragment? */
+ if (diff >= len)
+ {
+ /* Yes: insert the cell here. */
+ p->prev = t;
+ p->next = t->next;
+ p->base = (t->base + t->len) & (state->soup_size-1);
+ t->next->prev = p;
+ t->next = p;
+
+#if TRACE_SOUP_ALLOCATIONS
+ printf ("%d OK\n", p->base);
+#endif
+
+ return p;
+ }
+
+ offset += diff + t->len;
+ t = t->next;
+ }
+ while (offset <= state->soup_size && t != mother_frag);
+
+ /* No space for it. */
+ state->soup_free += len;
+ free (p);
+
+#if TRACE_SOUP_ALLOCATIONS
+ printf ("FAILED\n");
+#endif
+
+ return 0;
+ }
+
+ /* Find a suitable fragment near the mother. */
+
+ /* Search forwards first. */
+ t = mother_frag;
+ offset = 0;
+ do
+ {
+ int diff;
+
+#if TRACE_SOUP_ALLOCATIONS
+ printf ("[%d,%d:%d,%d] ",
+ t->base, t->base + t->len,
+ t->next->base, t->next->base + t->next->len);
+#endif
+
+ /* Handle the wrap-around case gracefully. */
+ if (t->next->base > t->base)
+ diff = t->next->base - (t->base + t->len);
+ else
+ diff = t->next->base - (t->base + t->len) + state->soup_size;
+
+ /* Is there space after this fragment? */
+ if (diff >= len)
+ {
+ /* Yes: insert the cell here. */
+ p->prev = t;
+ p->next = t->next;
+ p->base = (t->base + t->len) & (state->soup_size-1);
+ t->next->prev = p;
+ t->next = p;
+
+#if TRACE_SOUP_ALLOCATIONS
+ printf ("%d OK\n", p->base);
+#endif
+
+ return p;
+ }
+
+ offset += diff + t->len;
+ t = t->next;
+ }
+ while (offset <= MAX_SPAWN_DISTANCE && t != mother_frag);
+
+ /* Search backwards. */
+ t = mother_frag;
+ offset = 0;
+ do
+ {
+ int diff;
+
+#if TRACE_SOUP_ALLOCATIONS
+ printf ("[%d,%d:%d,%d] ",
+ t->prev->base, t->prev->base + t->prev->len,
+ t->base, t->base + t->len);
+#endif
+
+ /* Handle the wrap-around case gracefully. */
+ if (t->prev->base < t->base)
+ diff = t->base - (t->prev->base + t->prev->len);
+ else
+ diff = t->base - (t->prev->base + t->prev->len) + state->soup_size;
+
+ /* Is there space before this fragment? */
+ if (diff >= len)
+ {
+ /* Yes: insert the cell here. */
+ p->prev = t->prev;
+ p->next = t;
+ p->base = (t->base - len) & (state->soup_size-1);
+ p->len = len;
+ t->prev->next = p;
+ t->prev = p;
+
+#if TRACE_SOUP_ALLOCATIONS
+ printf ("%d OK\n", p->base);
+#endif
+
+ return p;
+ }
+
+ offset += diff + t->prev->len;
+ t = t->prev;
+ }
+ while (offset <= MAX_SPAWN_DISTANCE && t != mother_frag);
+
+ /* No space for it. */
+ state->soup_free += len;
+ free (p);
+
+#if TRACE_SOUP_ALLOCATIONS
+ printf ("FAILED\n");
+#endif
+
+ return 0;
+}
+
+/* Free up a soup fragment. */
+void
+soup_frag_free (struct state *state,
+ struct soup_frag *frag)
+{
+ /* NB. We ignore the case of freeing up the single last remaining
+ * fragment, since that should never happen in real life.
+ */
+ frag->next->prev = frag->prev;
+ frag->prev->next = frag->next;
+
+ state->soup_free += frag->len;
+
+ free (frag);
+}
+
+/* Compute the CRC for a frag. */
+crc_t
+soup_frag_compute_crc32 (const struct state *state,
+ const struct soup_frag *frag)
+{
+ /* Take care of the case where a cell straddles the end of the soup. */
+ if (frag->base + frag->len <= state->soup_size)
+ {
+ return compute_crc32 (state->soup + frag->base, frag->len);
+ }
+ else
+ {
+ crc_t crc = compute_crc32 (state->soup + frag->base,
+ state->soup_size - frag->base);
+ return incr_compute_crc32 (crc, state->soup,
+ frag->len - (state->soup_size - frag->base));
+ }
+
+}
+
+/* This function checks that the soup is consistent. We are passed
+ * one fragment (at random) and walk the circular linked list,
+ * examining the fragments to ensure they are in order and do not
+ * overlap.
+ */
+void
+soup_check (struct state *state)
+{
+ const struct soup_frag *start_frag = _cell_get_any_frag (state);
+ const struct soup_frag *frag = start_frag;
+ int nr_frags = 0;
+ int soup_free = state->soup_size;
+
+ do
+ {
+ assert (0 <= frag->base && frag->base < state->soup_size);
+ assert (frag->len > 0);
+
+ assert (frag->next->prev == frag);
+ assert (frag->prev->next == frag);
+
+ if (frag->prev->base < frag->base)
+ assert (frag->prev->base + frag->prev->len <= frag->base);
+ else
+ assert (frag->prev->base + frag->prev->len <= frag->base + state->soup_size);
+
+ if (frag->base < frag->next->base)
+ assert (frag->base + frag->len <= frag->next->base);
+ else
+ assert (frag->base + frag->len <= frag->next->base + state->soup_size);
+
+ soup_free -= frag->len;
+
+ frag = frag->next;
+ nr_frags++;
+ }
+ while (frag != start_frag);
+
+ assert (nr_frags == state->nr_cells_allocated);
+ assert (soup_free == state->soup_free);
+}
+
+/* Dump the soup and soup structures out to a file. This function is
+ * non-destructive.
+ */
+void
+soup_state_save (struct state *state, FILE *fp)
+{
+ struct soup_frag *start_frag, *frag;
+
+ /* Write out the size of the soup. */
+ fwrite (&state->soup_size, sizeof state->soup_size, 1, fp);
+ fwrite (&state->soup_free, sizeof state->soup_free, 1, fp);
+
+ /* Write out the soup itself. */
+ fwrite (state->soup, 1, state->soup_size, fp);
+
+ /* Write out the number of fragments. Note that this is the same
+ * as the number of allocated cells.
+ */
+ fwrite (&state->nr_cells_allocated,
+ sizeof state->nr_cells_allocated, 1, fp);
+
+ /* Write out the fragment list. */
+ frag = start_frag = _cell_get_any_frag (state);
+ do
+ {
+ fwrite (frag, sizeof (struct soup_frag), 1, fp);
+
+ frag = frag->next;
+ }
+ while (frag != start_frag);
+}
+
+/* Load the soup state from a previously saved file. */
+void
+soup_state_load (struct state *state, FILE *fp)
+{
+ int _soup_size, nr_frags, i;
+ struct soup_frag *first_frag = 0, *prev_frag = 0;
+
+ /* Load the size of the soup expected. */
+ if (fread (&_soup_size, sizeof _soup_size, 1, fp) != 1)
+ {
+ fprintf (stderr, "error in soup state\n");
+ abort ();
+ }
+ if (state->soup_size != _soup_size)
+ {
+ fprintf (stderr, "soup size doesn't match - can't load this soup image\n");
+ abort ();
+ }
+ if (fread (&state->soup_free, sizeof state->soup_free, 1, fp) != 1)
+ {
+ fprintf (stderr, "error in soup state\n");
+ abort ();
+ }
+ if (state->soup_free > state->soup_size)
+ {
+ fprintf (stderr, "soup free > soup_size - can't load this soup image\n");
+ abort ();
+ }
+
+ /* Load the soup itself. */
+ if (fread (state->soup, 1, _soup_size, fp) != _soup_size)
+ {
+ fprintf (stderr, "error in soup state\n");
+ abort ();
+ }
+
+ /* Load the number of fragments expected. */
+ if (fread (&nr_frags, sizeof nr_frags, 1, fp) != 1)
+ {
+ fprintf (stderr, "error in soup state\n");
+ abort ();
+ }
+ if (nr_frags != state->nr_cells_allocated)
+ {
+ fprintf (stderr, "nr_frags != nr_cells_allocated - can't load this soup image\n");
+ abort ();
+ }
+
+ /* Load each fragment. */
+ for (i = 0; i < nr_frags; ++i)
+ {
+ struct soup_frag *p;
+
+ p = malloc (sizeof (struct soup_frag));
+ if (p == 0) { perror ("malloc"); abort (); }
+
+ if (fread (p, sizeof (struct soup_frag), 1, fp) != 1)
+ {
+ fprintf (stderr, "error in soup state\n");
+ abort ();
+ }
+
+ if (i == 0)
+ first_frag = p;
+
+ /* Find the cell which references this fragment and fix it up. */
+ _cell_fixup_soup_ref (state, p->base, p);
+
+ /* Join the fragments to form a circular linked list. */
+ if (prev_frag)
+ {
+ p->prev = prev_frag;
+ p->prev->next = p;
+ }
+
+ prev_frag = p;
+ }
+
+ /* Finish off the circular linked list. */
+ first_frag->prev = prev_frag;
+ prev_frag->next = first_frag;
+}
--- /dev/null
+# DLIFE soup configuration file.
+
+#----------------------------------------------------------------------
+# The size of the soup (in bytes).
+#
+# This parameter must be a power of 2. If you change this parameter,
+# then you will have to reinitialize the soup image. You cannot load
+# a soup image from one version of the program into another version
+# with a different soup size.
+
+soup_size 131072
+
+#----------------------------------------------------------------------
+# Failure probabilities.
+#
+# All probabilities are expressed in the form ``1 in N'' where N is
+# an integer between 1 and about 4 billion. Larger values of N means
+# the event is rarer. You can dramatically change the behaviour of
+# the environment by changing these parameters - from a highly-
+# irradiated soup similar to the early earth (and NOT supporting
+# life) - to an almost completely stable soup free from almost any
+# mutation.
+
+# The probability that fetching a value from the soup will fail.
+
+soup_fetch_failure 1000000
+
+# The probability that the program counter will fail to increment
+# after an instruction has been executed.
+
+inc_pc_failure 1000000
+
+# The overall probability that an instruction will fail to execute
+# correctly.
+
+insn_exec_failure 1000000
+
+# The probability that the access control mechanisms (which govern
+# what addresses a cell may write to) will fail. It is OK to have
+# this probability quite large (ie. small N) so that cells may try
+# to ``invade'' other cells.
+
+access_control_failure 10
+
+# The probability that a newly created cell isn't initialized correctly -
+# ie. that the registers and stack don't start off at zero.
+
+cell_initialization_failure 1000000
+
+#----------------------------------------------------------------------
+# Grim reaper configuration.
+#
+# These parameters control when and for how long the grim reaper
+# comes to life and kills off sick cells. These two parameters are
+# expressed as percentages of soup used (ie. ``80'' means the soup
+# is 80% full).
+
+# The grim reaper is invoked when the soup is this full.
+
+reaper_invoke_threshold 80
+
+# The grim reaper runs until the soup is this full (and then
+# goes back to sleep again).
+
+reaper_reap_threshold 79
--- /dev/null
+/* DLIFE Copyright (C) 2000 Richard W.M. Jones <rich@annexia.org>
+ * and other authors listed in the ``AUTHORS'' file.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id: soup.h,v 1.1 2002/04/05 14:40:28 rich Exp $
+ */
+
+#ifndef soup_h
+#define soup_h
+
+#include "config.h"
+
+#include "types.h"
+#include "state.h"
+#include "crc.h"
+
+/* How far away can a daughter be from its mother? */
+#define MAX_SPAWN_DISTANCE 8192
+
+struct soup_frag
+{
+ addr_t base; /* Base address of this fragment. */
+ int len; /* Length of this fragment. */
+
+ /* These are kept on a circular doubly-linked list. */
+ struct soup_frag *next, *prev;
+};
+
+extern inline addr_t
+raddr_to_addr (const struct state *state,
+ const struct soup_frag *frag, reg_t raddr)
+{
+ return (frag->base + raddr) & (state->soup_size - 1);
+}
+
+extern inline int
+get_soup (const struct state *state,
+ const struct soup_frag *frag, reg_t raddr)
+{
+ addr_t addr = raddr_to_addr (state, frag, raddr);
+ return state->soup[addr];
+}
+
+extern inline void
+set_soup (struct state *state,
+ const struct soup_frag *frag, int v, reg_t raddr)
+{
+ addr_t addr = raddr_to_addr (state, frag, raddr);
+ state->soup[addr] = v;
+}
+
+extern void soup_init (struct state *state, int _soup_size);
+
+extern struct soup_frag *soup_frag_malloc (struct state *state,
+ struct soup_frag *, reg_t);
+extern void soup_frag_free (struct state *state, struct soup_frag *);
+
+extern void soup_state_save (struct state *state, FILE *fp);
+extern void soup_state_load (struct state *state, FILE *fp);
+
+extern void soup_check (struct state *state);
+
+extern crc_t soup_frag_compute_crc32 (const struct state *state,
+ const struct soup_frag *frag);
+
+#endif /* soup_h */
--- /dev/null
+/* DLIFE Copyright (C) 2000 Richard W.M. Jones <rich@annexia.org>
+ * and other authors listed in the ``AUTHORS'' file.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id: state.c,v 1.2 2002/04/05 16:47:13 rich Exp $
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "state.h"
+#include "soup.h"
+#include "cell.h"
+
+struct state *
+state_malloc (int _soup_size, int thread_num)
+{
+ struct state *p = malloc (sizeof (struct state));
+ if (p == 0) { perror ("malloc"); abort (); }
+
+ p->cell_cycle = 0;
+ p->nr_cells_alive = 0;
+ p->nr_cells_allocated = 0;
+ dlink_list_init (&p->alive_list, offsetof (struct cell, next));
+ dlink_list_init (&p->best_list, offsetof (struct cell, worse));
+ soup_init (p, _soup_size);
+ p->filename = 0;
+ p->thread_num = thread_num;
+
+ return p;
+}
+
+void
+state_free (struct state *state)
+{
+ struct cell *p;
+
+ /* Free up cells. This also cleans up soup frags. */
+ for (p = (struct cell *) state->alive_list.first; p; p = p->next)
+ {
+ cell_kill (state, p);
+ }
+
+ /* Free up soup. */
+ free (state->soup);
+
+ /* Free up soup image filename. */
+ if (state->filename) free (state->filename);
+
+ /* Free up structure. */
+ free (state);
+}
--- /dev/null
+/* DLIFE Copyright (C) 2000 Richard W.M. Jones <rich@annexia.org>
+ * and other authors listed in the ``AUTHORS'' file.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id: state.h,v 1.1 2002/04/05 14:40:28 rich Exp $
+ */
+
+#ifndef state_h
+#define state_h
+
+#include "dlink.h"
+#include "types.h"
+
+struct state
+{
+ /* The number of cycles we have been running for. */
+ unsigned long long cell_cycle;
+
+ /* The number of cells alive (running and on the alive list). */
+ int nr_cells_alive;
+
+ /* The number of cells allocated (alive + undivided daughters). */
+ int nr_cells_allocated;
+
+ /* The list of cells currently alive (running). Some cells may also
+ * exist in an undivided state.
+ */
+ dlink_list_t alive_list;
+
+ /* The same list of cells, kept in order of best (fewest errors) to
+ * worse (most errors). This allows the grim reaper to quickly remove
+ * dying cells.
+ */
+ dlink_list_t best_list;
+
+ /* The soup. */
+ byte_t *soup;
+
+ /* Number of bytes in soup, and number of bytes free in soup. */
+ int soup_size;
+ int soup_free;
+
+ /* Filename of the soup image (for this thread). */
+ char *filename;
+
+ /* Thread number (first thread is number 0). */
+ int thread_num;
+};
+
+extern struct state *state_malloc (int _soup_size, int thread_num);
+extern void state_free (struct state *);
+
+#endif /* state_h */
--- /dev/null
+/* DLIFE Copyright (C) 2000 Richard W.M. Jones <rich@annexia.org>
+ * and other authors listed in the ``AUTHORS'' file.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id: types.h,v 1.1 2002/04/05 14:40:28 rich Exp $
+ */
+
+#ifndef types_h
+#define types_h
+
+#include "config.h"
+
+/* Apparently these are now defined by the ISO C 9x standard. */
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#else
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+
+typedef signed char int8_t;
+typedef short int16_t;
+typedef int int32_t;
+#endif
+
+typedef uint8_t byte_t;
+typedef int32_t addr_t;
+typedef int16_t reg_t;
+
+#endif /* types_h */