From 0aec1163718450d8bfd64e42b053940a742e031a Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Fri, 25 Apr 2014 11:39:16 +0100 Subject: [PATCH 1/1] Add to git. --- .cvsignore | 22 + AUTHORS | 5 + Build | 57 ++ Build.local | 62 ++ COPYING | 340 ++++++++ Changelog | 9 + INSTALL | 106 +++ Makefile+ | 108 +++ Makefile.am | 117 +++ Makefile.in | 590 ++++++++++++++ README | 22 + acconfig.h | 16 + aclocal.m4 | 170 ++++ archproc.fig | 152 ++++ archproc.gif | Bin 0 -> 8448 bytes archref.html | 489 ++++++++++++ cell.c | 703 +++++++++++++++++ cell.h | 122 +++ client.conf | 46 ++ config.cache | 0 config.h.in | 95 +++ config.log | 20 + configure | 1902 +++++++++++++++++++++++++++++++++++++++++++++ configure.in | 252 ++++++ crc.c | 142 ++++ crc.h | 33 + debian/changelog | 9 + debian/conffiles | 4 + debian/control | 24 + debian/copyright | 11 + debian/cron.d | 2 + debian/dirs | 3 + debian/docs | 7 + debian/files | 1 + debian/init.d | 42 + debian/postinst.debhelper | 11 + debian/postrm.debhelper | 5 + debian/prerm.debhelper | 8 + debian/rules | 64 ++ debian/substvars | 1 + dlife.rc | 49 ++ dlife.spec.in | 91 +++ dlife_asm.pl | 356 +++++++++ dlife_client.cron | 2 + dlife_client.pl.in | 397 ++++++++++ dlife_disasm.pl | 147 ++++ dlife_server.pl.in | 222 ++++++ dlink.h | 146 ++++ exec.c | 556 +++++++++++++ god.dla | 90 +++ god.dlo | 56 ++ image.c | 106 +++ image.h | 30 + index.html.in | 111 +++ install-sh | 1 + load.c | 116 +++ load.h | 29 + machineref.html | 746 ++++++++++++++++++ main.c | 483 ++++++++++++ missing | 1 + mkinstalldirs | 1 + params.h | 44 ++ random.c | 50 ++ random.h | 69 ++ servers.txt | 3 + soup.c | 440 +++++++++++ soup.conf | 65 ++ soup.h | 79 ++ stamp-h.in | 0 state.c | 67 ++ state.h | 66 ++ types.h | 43 + 72 files changed, 10434 insertions(+) create mode 100644 .cvsignore create mode 100644 AUTHORS create mode 100755 Build create mode 100755 Build.local create mode 100644 COPYING create mode 100644 Changelog create mode 100644 INSTALL create mode 100644 Makefile+ create mode 100644 Makefile.am create mode 100644 Makefile.in create mode 100644 README create mode 100644 acconfig.h create mode 100644 aclocal.m4 create mode 100644 archproc.fig create mode 100644 archproc.gif create mode 100644 archref.html create mode 100644 cell.c create mode 100644 cell.h create mode 100644 client.conf create mode 100644 config.cache create mode 100644 config.h.in create mode 100644 config.log create mode 100755 configure create mode 100644 configure.in create mode 100644 crc.c create mode 100644 crc.h create mode 100644 debian/changelog create mode 100644 debian/conffiles create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/cron.d create mode 100644 debian/dirs create mode 100644 debian/docs create mode 100644 debian/files create mode 100644 debian/init.d create mode 100644 debian/postinst.debhelper create mode 100644 debian/postrm.debhelper create mode 100644 debian/prerm.debhelper create mode 100755 debian/rules create mode 100644 debian/substvars create mode 100644 dlife.rc create mode 100644 dlife.spec.in create mode 100644 dlife_asm.pl create mode 100644 dlife_client.cron create mode 100644 dlife_client.pl.in create mode 100755 dlife_disasm.pl create mode 100644 dlife_server.pl.in create mode 100644 dlink.h create mode 100644 exec.c create mode 100644 god.dla create mode 100644 god.dlo create mode 100644 image.c create mode 100644 image.h create mode 100644 index.html.in create mode 120000 install-sh create mode 100644 load.c create mode 100644 load.h create mode 100644 machineref.html create mode 100644 main.c create mode 120000 missing create mode 120000 mkinstalldirs create mode 100644 params.h create mode 100644 random.c create mode 100644 random.h create mode 100644 servers.txt create mode 100644 soup.c create mode 100644 soup.conf create mode 100644 soup.h create mode 100644 stamp-h.in create mode 100644 state.c create mode 100644 state.h create mode 100644 types.h diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 0000000..d43da9b --- /dev/null +++ b/.cvsignore @@ -0,0 +1,22 @@ +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 diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..a576e60 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,5 @@ +Richard Jones + * Main author and maintainer. + +Falk Hueffner + * Contributed Debian package. diff --git a/Build b/Build new file mode 100755 index 0000000..36526ba --- /dev/null +++ b/Build @@ -0,0 +1,57 @@ +#!/bin/sh - +# DLIFE (C) 2000 Richard W.M. Jones +# 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. diff --git a/Build.local b/Build.local new file mode 100755 index 0000000..98f2fa5 --- /dev/null +++ b/Build.local @@ -0,0 +1,62 @@ +#!/bin/sh - +# DLIFE (C) 2000 Richard W.M. Jones +# 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 diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..eeb586b --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + 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. + + 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.) + +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. + + 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. + + 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 + + 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. + + + Copyright (C) 19yy + + 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. + + , 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. diff --git a/Changelog b/Changelog new file mode 100644 index 0000000..77f7547 --- /dev/null +++ b/Changelog @@ -0,0 +1,9 @@ +2002-12-10 Nix + + * 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. diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..a8b6661 --- /dev/null +++ b/INSTALL @@ -0,0 +1,106 @@ +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). diff --git a/Makefile+ b/Makefile+ new file mode 100644 index 0000000..25e364b --- /dev/null +++ b/Makefile+ @@ -0,0 +1,108 @@ +# -*- 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 + +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 + +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. + +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 diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..a30745f --- /dev/null +++ b/Makefile.am @@ -0,0 +1,117 @@ +# DLIFE (C) 2000 Richard W.M. Jones +# 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 diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..7bef584 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,590 @@ +# 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 +# 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: diff --git a/README b/README new file mode 100644 index 0000000..c43cf96 --- /dev/null +++ b/README @@ -0,0 +1,22 @@ +Distributed Artificial Life (DLIFE) +----------------------------------- +By Richard W.M. Jones + +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. + diff --git a/acconfig.h b/acconfig.h new file mode 100644 index 0000000..b0193eb --- /dev/null +++ b/acconfig.h @@ -0,0 +1,16 @@ +#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 */ diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..2361d00 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,170 @@ +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>>, <<[^ ]>>, <<>>), <<>>, +<>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>, +<>; 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]) + diff --git a/archproc.fig b/archproc.fig new file mode 100644 index 0000000..eb6819a --- /dev/null +++ b/archproc.fig @@ -0,0 +1,152 @@ +#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 diff --git a/archproc.gif b/archproc.gif new file mode 100644 index 0000000000000000000000000000000000000000..7c5eabc450a6ad933ea50c772409a9d7aedd9fc6 GIT binary patch literal 8448 zcmV+bA^+Y-Nk%v~Ve0|g0m1+P0002Mz`%fjfdBvhKtMnM0000000000EC2ui0P6wU z0RRL3IJ(^aFv>}5132r=yZ?YCj$~<`XsViE>%MC&&vb1&;Z5aw@Bcs@FUS}YkH}=t zcw{P{(CEq;q)M+?sr9$bdcV-_5=<@w#X_@seGaqV@DlnqkK6A>H-5jb*Zh2eW`Hw< zf`>?kF^Y(dPmC&%j*~Q!D3+9&bb6YdiJYFHpr4|pOE0Jy7MP~3tEs80uCp?%3v;%# zx_OndyT2s41GvD&k$=9%$`HcD%g@QR(a_J$)703!h1c1@))m6tncq9&%j6T`=8otR z>g#ds5%2JV^33(#$l&?d_Yd^?4cb>uU^Rm24AT0CL*Y4u?i{*ectN5uirOrO!g&5m zqrP7JJZ^+IPvkC+3IduOHHF*Cksu4cq|_|d%vLo~-K0qp-_BAfhy7&N6W~x$K~)~* zQncaHPD!8IYg$q2II0<~+Q|t+>m;r&yyA%}wh`H~aL%F)q;{>Ewr=mhjSFTj-8Xjc zVgcJi@7O;!{no|WQE)uMDGd*fnNTra#6lfs$t!s>WTlm5N(-5}4CT&kDg_4pg)a!w zERS(UZJBXI)=56YZgP1xscoxmr%vHacWB(2eJhbIyrt`s#UIs9KIXVj=C?NohYnnN zW9meRV-L1``)}*7y@NMCUAztL=F9VTnSQ)#_3cNXkI&t?QTms<*z?%nra zfcfP%pn>lJc;I^WIkljFEI{}mf(*hpVO9Jgci{>1E!g3PS&^q8hz=5nA&K(ohvJF- zQMjUpCWiQ8WEnm;qlFQ=h~kGks(2%hBm%jgkQ)+7pOF(H*`AUf`Zyz#2SO>Hl>bq= zot5}uNu8GQamk#Q>490Cm{U6WBAMQyshgVEu{oQY(80-?oXOEinw`So*_obenzj|+HtNBmkVY!$q?A@_>7|%vs_CYjcIxS;poS{ysHB!^>Zz!v zs;WT(1Ta9W3J9=(00Iz@MF6s{>M5$Kcz`)as62oNr|G%jnYx4p(2*|7l7TCW4P23xPX zwEilstoz=}1OTpXJ8WjK!WwL>>|O!vk_^k61GHO!D{HjK<~j_y7>779z$hB)s{+7k ze8s_KeJpXr9dqkI0N=LU?5x|$+-_p=qAZ!n4J6xIdeja;?acG$N^PyKHjuBaM|sC!)zt37LvabsFoGh&{ z<2`G}uJ+3e(y zEbqqS8ZmIhSl=jmke%nMvds;A?JW;PzgjcxHy@t*jDv$1^w6HmD>c50OZ{}x!&9Bo z)Hu6)Dcrs09XH*YXRI;a&1!D4-hSgc_2a!eUn=H$ry>6NL9CAc`Za{l{`>HwuQ(Ld zlQ{nq^-HS$6Af>8Z5I8L)V;6}t$bZ5T2R9RzbIufVI}ZE;0jl19=IrV4R9|Q$RB

ZYTa)|64>6O8_^RsV)Rj{9sGA7$z99 z5CcLK0Ty?Mur$g?j4{~Oerz~{2)c0ua(t2%MexEqT3~blo8l(*!pa@05|pU-_N~W6U@xeCZGs{@gV49>+S1$_$Of&xHnj-pxH?ua*7BweH=DR^TQPW9% zy0eb+EY3dJ$;;w^Q=b8?06NpO&J^`vp#GH+BoKlL&;>124nDXjJsZj!j&kvz>7i(X zx@j9_Rv|kc%~MKs6a$Uk<)HWc0Ys@YQ*QbIp5FxN4O}YCY+41U_I#*LH<|>I(g3Je zV#*m-suhzG!KgFfscmX%Qy)-uEfQ1$R11;NJ291|r0fh#x$spIT(zW185UCGBGK3k zr>t%KPDXu-4W~xusa?%XJx6-eyxydrM3Cwk+jCZ9%9O6p80$p+N`kfe#zo zSo|UOCBs5lVSi%RqB1rZa5c`9}r*JK_{XM$ac zY-bAv$f9PeK_!B3ccM-JvbG1g{ymgyUmMuVx&pOY{j3Rwi?HLyNC?u+2VnV^U9&pZ zA=Kq-5Jqc}-3qt6ppBDTAF*6>v~@4WWe#}_dxZH41iHH!&X?ND+#@8nANb9062ePQ z{q`2U)G%*-t^0%jx&^p3YOYiiTwes2(85QlZG_LelmJ5k!ZKyBVC+j@B#^ip9zJkg z_e%X$?8DBaAL3QZkRQO28GxA1qXX2#}3s3i+Ax}GJMy?SRHbIm4M`Iq&Nyd zZs~VX%*Jf`_#7BsVwPF3Ws!imK}cw_jz!E}Ger3(8iveaO|oP5zD3DiCNr2z>yam) zYz<#7i98zM;W!uu380@klu% zWp09&S7YVTl!E@l)xd6s?_uY4{jSGhzJ{Lrd=EtL2D#DQ@n4*L#(@AjG)m5NiPPfg z2w(VKXx<8&yByV8A9&bl%=Hs^{TE5E>Kdrt>#>vFEI9wgrad09uCv|WWjA}?J#qG& zySf!ve~TleUW~gR{0(W>!rrgj>%~)o@WFlq@!=FIvC7*o}eBL6;kNCi;Kaa|*-V@O`#?s{)2j-*T z_~-A0`~Kl>?BH8Jk=^$^`5ztU!|-ALBd~q(aDUOpX3v*@ML>YTuz!3ucnD~D{-zfAt-+TM|T#a zHoCBWcs7EWCl`o7FgQpD8SsLYRSGd^e>`{y&Z2oCB!o-V3MfcyIw($putrZP0xDE^ zrdD42_ke7pNM=w#7cmRlwGIf#g$uwzX2yh16@^*HDmc^!W|2X0C5CEngF7X8GoC|}KVu9>#FG2|m}h{{ z1wxrSVkb0C<2rRWJW5k9@S-xwgEJG;H@0FpIH6+?$d2*ij$YF(4D~o#^N<}33%z40_J#2eKU|MQ;?kmHC2f^3u!eb znU?z)Q@TJt9GOJ@$VHclg*OS6VYvmSLzkb~kam+8Z#iL^IYg%^cOQ8;u#PkF^d^5S1FpWqLrJO9l9clXc3okGd+L#0Cp)d zh3P7KnU~S%EX9bMRd*_ZsSuR8T)N33-svv1_?-o&2^L9>Z>UDUvXTDF$U@x7Tcntp z$+<8k1Cx|AllHk7sWP79HITG9YOUq~0D2Oua-cc@mR$2K)&e%MLzVM*G4-gHTgjH< zB9K;rp5_*x6`-Lw={gI!lf%g?lEaX*87rj|nP}!|mN}T3`4y}AI-Xe-Jy{hgdXoKF z8nxI`FS!)ys4^kSEx5Cjg>j=KW1J3In>%`RU+7l~nwu~xTujrO1SypaAe;%wE5-Sf z3A2>~3Z!rVFW+J|t+FjcqnKhtGDlM@7Sk;Sqb*G%5K+2J)OnZ3Qa%QXopDp0f0H-X znVo(aJ)Bg3^1?IN!lf5^s79lrwzE7;DGqhoV{kK{EQnQxn*OKR8I6QApesX~oXMfQ z*QDu2st`zWo{FgL_$?VzcL@{%!6T}3wiA1a7IY^^dFn0q$f=8ys=flIpDL@&7(Z$j z1sqd8c(bX!qBxmTK6{xx&1$OpMy&b72A1j=rRWh*nyuo9XRtA;#06LRX%_z}tFyHyJ8BL(`T+8vD#fv3bO5+qkmO@a>Tt4q`WvQ6rOXK zhv^hvYBHwFF#R)}>7seNSim32GqOXqHVdjbdytKLy^;Eeen>L=a^q2%c`)_ z%M7?8v1f^u%u_(v0;{t*wDh)%PphI)%d5-VzRYWwo2R8TvbFL%6CP)cwUaOjLo*7a zohq7_+xb0dr2XOW6Efos0Xdex}1H_ z?0Gy&&@0?CP9rq5ygarXjkvtbH7Se~UC~K83`_GX##~Fctjrnv(a#vt{sx?mx~~ka zvjdvVt-H-^>KKFQC_LTMp#J==fn3h#TsP@#IC`6`aVs=z%y$rpzGD0zXuARey>DRT z)DdW6eN&9InUU`q1FDM`BWSMeC!AK@vK4lyfsqOMt@0MnSk zi!8MJ*76n6eLXAnQ<+iSk)dHYG|F5f8Jam7l%D-1d&mSS^s3cD%z-$iC?lkl4cM`X z1J$$Iz5SC*>cEW+!Zuk1{?f^_dkb5JGQ3GNhl!(;yz<7Li#G zoXcqh&j<=-0R`eAE*2!Nq^m3-VbX5PW?~}FV@lQFVOk>Qu}RtH<2TOB=A+{*%F<<` z;x&HOHl~~~zTrlmCN!RVHtymqUgbK`B^hJo9#A(w9_98erjM&+;If^uWG`Coz1kDx zUoM56JW>6-L;84A2}G0YX^dP=GVu9eFIx|~+XRfwO%SIl?2aJ+E!*x%b*Ma~hixTDtxU*fi^ZnziHgQS7k(e%w2xh&ey>tUH>` zwX&PPE{?JPtf*?Oya>CM4cjiyPPVuE!B36sUB1gU;N&fW+MlD^poyc8$)t9$>6~c1 z%F4bmd&BR`(joi3M@a4~?&%1X?0`YFy>-&9NOkqxu-o}3F@uneicAA8Lp z$+Oa4fBw!O8*hA73f)l&(^Cn$RteJz|D`c*fsN?FWMj1rZOJU}@(&y})Q!uVErS=*w*d;vOGX*x}}WvoL1j9IrgL__p|`co?4RP3zdy@wVZ~j z=H5O#A8~Ylt_pay>;gSPQOtb5C}98TVn5}EtPFhbm{@c~)tv8)pYwn(@VN{5YED2~ zOf<=YIqseHT>K-Ne@vWzAA`TYuL#XPzkT2FcGp$-;@xoIU1a!_S-CKuWtA#2@Og75N|WVgBxR zqND6A3H__5?5Nm2(+`dO-`^PVUjf_N&4os3ND#{xz4!WEwjbHi2p}@bI}pH0tGzhu z&8-|?CvHtMdeNy~<+D;k@LIv*&UikD`fT>6Ku886KnM@nPe3rjYzqKU(sEFEz^oRO z+LEBT57uj`=4#m=dEFbcG3vLa$s{r%LWNN+tyJ$N1OZJ}cusPN9Ab%2g*#o0R>W z1A_zrbb|{`LNZ856PJ3JF`%EIbcdDzfSFWute24}v}HH83PhH>H4DDGtCnUpySg#D zN4vJRi?pGWC(e;(I3Xr~dz=tA*bh#CPJKLml^JPH8t@$&QZ{`K`S6VdEJ zxH7N-=___E6#j|xFDNXbUP2YoD~N@a5`lY*;Q zvufSSHIvRTc#6u22~`9^Y=Q_?ak9!AH*G@|mNM5)T^Bb3BLI}sr|i_ffUQyFO1SXW zWqvnQMPj(IVXqx=3>t>d0h)-ot^&h@513{($*z7K_OCLtkBF)TUd=k^$;2A4IG#-y zam@~M#V`8Z;e`x>gCW`A5WD0!t~Vsx1(#no9p-X?^3Tj z&u*M$b@0HOzj=?P>n zgE$x{VO9g4`~4qbzIU)CzIvVL?1c&WQr-JEES!MUeFkxJy1p|C6q1-H{q4J-59|;oNU7c6BxZU z3=D9A1D9&z{l(-KPDYjHehGewWr07vFsFntZg7*3Xdw856v9+-ktE)2wA`9nw8_$& z3|6_DClO33={<@$`qrHR*15u-Q?QkUBTNJe#!F$MxupJy|8+POqcd9CT1=W|u_p$z zjsPhLlja&vO%vguiXBem0muzv5vpV$v-}X`p{VYMVkE3K>FR1X)w)Hj6=1sotW5P_ zZ3W++kPIHZG_ctb;1XlnG3QnS9inLz8d$V!PCM^6_Uc(Ixch2QExl%S8%;J@o9|Rd9km|8N{-Mgf?nK8YrlM9yu!q%DcmZ z(W`OfRV=a&7Q=C~mWjX%grX-swX;f3k<1de1x*(&zcR#36|Y9~ESRCl$qSemD+AG2 z)cgGV49410fOH~Dhb8r*CQFMl+Ei0#wRXMEO#U{=VUg%{Bw-&h^x0nctkT=7rd{va zz}d`9&MXidH`n^wO*h{%3$6u2y7`SW;KJPs@#gl_#IcZK=7KTekoSB9;~CuaY+h}1 zxVlt%|MjiroY%hVwy2k0o-7N2le^ZE$4hu?Wd{~(>{Au5yB3RKx)o%@?_+rmKr?6i z^_(xG{9ni~-^O6hV`W?A!T*f8_bp+szOGrLzXHI*m)QD=zq@b${pFu5Km2x{kN^Jw z)R=kdr-SK5$bSJ$paLtvzrT@heyMuh0w=gU_=Imh1Oy8Nos~ffdhkORlu!GV(m)kd z?}I2zp^Xga0|ct@g)saO3;P$n7@}`|{1JH z29yI4J}Tn^Jtz_bLZe2}0%JJmjBanN`y3loCr5UeAqh74q;>T29woH0alAu>+^lm; z#ni2LE`!i>Ac?{}n$U%KV+$%VWXFVY!zx>Z9x(&s3(6T}6h>kSD1LE@O?a~jjl7>R z#f8kd4HB3dFr?|8u*LB~s1j!W7$pd}GzV@Bz)Z%v!}b`U1Uu+tnd!MC4X0VajL4Ca z6hNpK?cOCj6ie_zpCdwk7a|j>;W$R(gPT- zsfiq2V4IfcCKA30PACFTrYEB*B>>8ded=R)cE+iVuw8#a;(8*=C$^m#*v?K7@ z&up+_p?B0kN7rE1sHpR4TjXL;b>j=o98&}iZK=7ABhf)cM4(d(Yz78P2A_KN zv!D&_XT4gl#2SXQ_*4F+P~&-0QKXa*E4?gOse;+ZidB}ljYM2KKnSBs_8X^A>Qg1* zRHgzJk&Df(a*rq)U9i;~18OU2^*~Z56Rs1vR8}l)yiSxo1l$~fV1(nsb~kRR|bZczsIewcEw0Xn=})_ zeZ+2}%8B5+t)Y-)h46R$>r(r2cVqQa=r1*_A`Wu^z~n9E#Ym8062B|G;PtR_VfHvY zs?o(DGVvE=oZALZ^1(PJsf2~M;2l~RCSYrEkRPa73}liuoAl>Fl>9D((n7?!TylR; zr(1bK`8Tl4sQ!vnOpTCgdCOTIi|?BF(gSyS3IvYxXMuWV|1>X}hbZ!kFm{d0Q0SR0d-jzlMkwr$p|jsbJCitW=Ap4RGTC&- ztsN|daRKGb>Q?s@zMf_qs4Y3_QF7|FMu;s>S{mzKe{ZOeE~+4oYJ#Lzda1)&O0uBp z>t@$y)~ivgb6c>J=qgKMbDgiVx2=f$a^<|+@vgQv8)|OL(%ZH19=OfTZY}S&-SCdL zyys2tdfWTn_=X|6xdQ8a`x`v?-FK+|O>hM$PABoe~#=03`_jt z?g8=_a6YC3zmx5NIe-s&J+`tg13 zA8BG6)G7S{$6k{ih`&zX_-VKG*Lh7*Nq^t>;cqP-aGj2@?^@O8k2~Hkr1rhL3+l)| zQ*o0Wf8Qg%G*Ga3w*Xg;w-n>ne+bxk;`3Mu*nn^Fc@7wXDlmEySb-LJff$&98n}VE zkb7dbdmOldD0dklsDZ^-f)}WBea3TD#e9Jl3PD$BLwA2DNP5+$ck_gOO0^As*HqqD zgQS;!D`;xumuf=>gb^o%rM7-;2U~CVen*Ie3pan(XMcOa7Jj#XfhUE6_kW6a5Y|S3 i#()e4*m+!7be6|}XUKsNxP}Nwfo>Rwa>ybH002AB?1*{* literal 0 HcmV?d00001 diff --git a/archref.html b/archref.html new file mode 100644 index 0000000..5e5c20b --- /dev/null +++ b/archref.html @@ -0,0 +1,489 @@ + + + + DLIFE distributed architecture reference + + + +

DLIFE distributed architecture reference

+ +

+ 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. +

+ +

Processes

+ +

+ There are currently three processes involved: +

+ +
    +
  • dlife_soup: 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. +
  • dlife_client.pl: 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. +
  • dlife_server.pl: This is the DLIFE server + script. It only runs on servers (obviously). It acts + as a repository for cells being exchanged between + clients. +
+ +

+ The following diagram shows the interaction between these + three programs. +

+ + [Diagram] Interaction between DLIFE processes + +

+ 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 + /etc/ppp/ip-up.local (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 cron. Clients may connect and exchange + cells with more than one server. In the diagram + above, the third client computer connects to + both servers. +

+ +

Cells in files

+ +

+ 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. +

+ +

+ dlife_soup saves (by default) six cells per hour, + at random, into the directory: +

+ +

+ /var/spool/dlife/outgoing/ +

+ +

+ dlife_soup loads (by default) four cells per hour, + at random, from the directory: +

+ +

+ /var/spool/dlife/incoming/ +

+ +

+ The dlife_client.pl program takes some cells at + random from the outgoing spool + directory and uploads them to one or more servers + (see the configuration section + below). It then asks the server(s) to send some + cells, and it saves these in the incoming + spool directory. +

+ +

+ The dlife_server.pl program listens for client + connections, and uploads or downloads cells. It + saves its cells in the directory: +

+ +

+ /var/spool/dlife/store/ +

+ +

DLIFE network protocol

+ +

+ The DLIFE network protocol is a very simple + ASCII based protocol, similar to (but much + more limited than) FTP. +

+ +

+ Servers listen for connections on port 5904. + When a client connects, they send back the following + identifying string: +

+ +
+DLIFE SERVER <version> <protocol> <CR> <LF>
+
+ +

+ <version> is the server version, for + information only. +

+ +

+ <protocol> 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. +

+ +

+ Clients connect to servers on port 5904 and + issue a series of simple four letter commands. + Each command should take the form: +

+ +
+<command> [ <space> <arguments ...> ] <CR> <LF>
+
+ +

+ There are currently four commands: HELO, + STOR, RETR and QUIT. +

+ +

+ Servers respond to commands with a three digit + response code and some optional human-readable text: +

+ +
+XYZ [ <space> text ... ] <CR> <LF>
+
+ +

+ Of the response code, only the first digit (``X'') + is meaningful to clients. As for FTP, this digit can + have the following meanings: +

+ + + + + + + + + + + + + + + + + + + + + +
Response code Meaning
1xx Command OK. Ready to send data, or ready + to receive data. +
2xx Command OK. Ready for your next command. +
4xx Temporary error. The client can retry the last command + without modification and it may well succeed next time. +
5xx 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. +
+ +

The HELO command

+ +

+ The HELO command has the following form: +

+ +
+HELO <space> <client_hostname>
+          <space> <client_version> <CR> <LF>
+
+ +

+ 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. +

+ +

+ The server should always respond with 2xx to + this command. +

+ +

+ A typical interaction: +

+ +
+> HELO - 0.0.12
+< 200 Hello.
+
+ +

The STOR command

+ +

+ The STOR command is used to upload a single + cell to the server. +

+ +

+ The format of the command is: +

+ +
+STOR <CR> <LF>
+
+ +

+ 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 + <CR> <LF> . <CR> <LF>. +

+ +

+ A typical interaction: +

+ +
+> STOR
+< 100 Send me the cell, terminated by ".".
+> 00000000010901010100002227
+> 0000000100FFFFFFFFFFFFFFFF
+>      :      :
+>      :      :
+> 00010000002402020202020202022027
+> 0001010101
+> .
+< 200 Cell was uploaded OK.
+
+ +

+ 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. +

+ +

The RETR command

+ +

+ The RETR command is used to download + a cell from the cell bank. The format of the command + is: +

+ +
+RETR <CR> <LF>
+
+ +

+ 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 + <CR> <LF> . <CR> <LF> + and immediately followed by a 2xx response. +

+ +

+ A typical interaction: +

+ +
+> RETR
+< 100 OK. Sending you a cell.
+< 00000000010901010100002227
+< 0000000100FFFFFFFFFFFFFFFF
+<      :      :
+<      :      :
+< 00010000002402020202020202022027
+< 0001010101
+< .
+< 200 Cell was sent OK.
+
+ +

The QUIT command

+ +

+ The QUIT command terminates a session + (clients may also just close a session). +

+ +

+ The format of the command is: +

+ +
+QUIT <CR> <LF>
+
+ +

+ The server responds with a 2xx message and then + closes its end of the connection. +

+ +

+ A typical interaction: +

+ +
+> QUIT
+< 200 Goodbye.
+(socket is closed)
+
+ +

Configuration files

+ +

/etc/dlife/client.conf

+ +

+ This file is used to configure the network client. + The file tells the client which server or servers + to connect to. +

+ +

+ The client can be configured to: +

+ +
    +
  • Download a list of servers from a web page. +
  • Contact only servers in the current ``zone'' (eg. + only servers in the UK or Europe). And/or: +
  • Contact servers directly by name. +
+ +

server_url command

+ +

+ The server_url 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. +

+ +
+server_url http://dlife.annexia.org/servers.txt
+
+ +

server_zone command

+ +

+ The server_zone command is optional. It + should be used in conjunction with the + server_url command. It + directs the client to only consider servers + in the particular zone or zones listed. +

+ +

+ The general form is: +

+ +
+server_zone <zone> [<zone> [...]]
+
+ +

+ Each <zone> argument should have the + form: +

+ +
    +
  • An ISO3166 country code, eg. uk, us. Or: +
  • A geographical continent, eg. eu. Or: +
  • A domain name, preceeded by a dot ("."), + eg. .bibliotech.net. +
+ +

server command

+ +

+ The server command directs the client to + connect directly the server or servers listed. +

+ +
+server dlife1.bibliotech.co.uk dlife2.bibliotech.co.uk
+
+ +

max_cells_upload_per_pass command

+ +

+ The max_cells_upload_per_pass directs + the client to attempt to upload this many cells + in a pass. Note that the server probably imposes + its own limit. +

+ +

max_cells_download_per_pass command

+ +

+ The max_cells_download_per_pass 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 + max_cells_upload_per_pass > + max_cells_download_per_pass. +

+ +

/etc/dlife/soup.conf

+ +

+ The soup.conf file configures various + internal aspects of the DLIFE virtual machine. + For full documentation, please see the example + file provided with the source distribution. +

+ +

Typical configurations

+ +

Default configuration

+ + + + + + + + + + +
+
Richard Jones
+ + +Last modified: Wed Oct 11 23:19:19 BST 2000 + + + diff --git a/cell.c b/cell.c new file mode 100644 index 0000000..c7f1f1a --- /dev/null +++ b/cell.c @@ -0,0 +1,703 @@ +/* DLIFE Copyright (C) 2000 Richard W.M. Jones + * 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 +#include + +#ifdef HAVE_STRING_H +#include +#endif + +#ifdef HAVE_ASSERT_H +#include +#endif + +#ifdef HAVE_TIME_H +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_SIGNAL_H +#include +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#ifdef HAVE_DIRENT_H +#include +#endif + +#ifdef HAVE_SYSLOG_H +#include +#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); +} diff --git a/cell.h b/cell.h new file mode 100644 index 0000000..847fcf5 --- /dev/null +++ b/cell.h @@ -0,0 +1,122 @@ +/* DLIFE Copyright (C) 2000 Richard W.M. Jones + * 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 + +#ifdef HAVE_SYS_PARAM_H +#include /* 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 */ diff --git a/client.conf b/client.conf new file mode 100644 index 0000000..5bcb134 --- /dev/null +++ b/client.conf @@ -0,0 +1,46 @@ +# 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 diff --git a/config.cache b/config.cache new file mode 100644 index 0000000..e69de29 diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..d86b37c --- /dev/null +++ b/config.h.in @@ -0,0 +1,95 @@ +/* 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 header file. */ +#undef HAVE_ASSERT_H + +/* Define if you have the header file. */ +#undef HAVE_DIRENT_H + +/* Define if you have the header file. */ +#undef HAVE_ERRNO_H + +/* Define if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define if you have the header file. */ +#undef HAVE_GRP_H + +/* Define if you have the header file. */ +#undef HAVE_PWD_H + +/* Define if you have the header file. */ +#undef HAVE_SIGNAL_H + +/* Define if you have the header file. */ +#undef HAVE_STDDEF_H + +/* Define if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define if you have the header file. */ +#undef HAVE_STRING_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define if you have the header file. */ +#undef HAVE_SYSLOG_H + +/* Define if you have the header file. */ +#undef HAVE_TIME_H + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Name of package */ +#undef PACKAGE + +/* Version number of package */ +#undef VERSION + + +#endif /* DLIFE_CONFIG_H */ diff --git a/config.log b/config.log new file mode 100644 index 0000000..42174ee --- /dev/null +++ b/config.log @@ -0,0 +1,20 @@ +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} diff --git a/configure b/configure new file mode 100755 index 0000000..37fa179 --- /dev/null +++ b/configure @@ -0,0 +1,1902 @@ +#! /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 <> confdefs.h <&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 <&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 < +/* 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 <&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 < +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 < +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 < +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 +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 <&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 <> confdefs.h < 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 </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 < 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 <> $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 <> $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 <> $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 <> $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 + diff --git a/configure.in b/configure.in new file mode 100644 index 0000000..25b6ac0 --- /dev/null +++ b/configure.in @@ -0,0 +1,252 @@ +# DLIFE (C) 2000 Richard W.M. Jones +# 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 + ]) diff --git a/crc.c b/crc.c new file mode 100644 index 0000000..4694400 --- /dev/null +++ b/crc.c @@ -0,0 +1,142 @@ +/* DLIFE Copyright (C) 2000 Richard W.M. Jones + * 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); +} diff --git a/crc.h b/crc.h new file mode 100644 index 0000000..08db92b --- /dev/null +++ b/crc.h @@ -0,0 +1,33 @@ +/* DLIFE Copyright (C) 2000 Richard W.M. Jones + * 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 + +#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 */ diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..55a81db --- /dev/null +++ b/debian/changelog @@ -0,0 +1,9 @@ +dlife (0.0.15-1) unstable; urgency=low + + * Initial Release. + + -- Falk Hueffner Fri, 13 Oct 2000 05:49:22 +0200 + +Local variables: +mode: debian-changelog +End: diff --git a/debian/conffiles b/debian/conffiles new file mode 100644 index 0000000..94fdfa9 --- /dev/null +++ b/debian/conffiles @@ -0,0 +1,4 @@ +/etc/init.d/dlife +/etc/dlife/client.conf +/etc/dlife/soup.conf +/etc/ppp/ip-up.d/9dlife diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..b833da7 --- /dev/null +++ b/debian/control @@ -0,0 +1,24 @@ +Source: dlife +Section: misc +Priority: optional +Maintainer: Falk Hueffner +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. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..022b670 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,11 @@ +Distributed Artificial Life was debianized by Falk Hüffner +. + +It was originally downloaded from . There's a web +site for it at http://dlife.annexia.org/. + +The copyright belongs to its author Richard W.M. Jones +. + +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. diff --git a/debian/cron.d b/debian/cron.d new file mode 100644 index 0000000..bd3cf16 --- /dev/null +++ b/debian/cron.d @@ -0,0 +1,2 @@ +# Run the client to upload cells periodically. +5 * * * * dlife /usr/bin/dlife_client.pl diff --git a/debian/dirs b/debian/dirs new file mode 100644 index 0000000..e27bc8b --- /dev/null +++ b/debian/dirs @@ -0,0 +1,3 @@ +usr/bin +usr/sbin +etc/ppp/ip-up.d diff --git a/debian/docs b/debian/docs new file mode 100644 index 0000000..3c9ddd2 --- /dev/null +++ b/debian/docs @@ -0,0 +1,7 @@ +AUTHORS +README +archproc.gif +archref.html +index.html +machineref.html +servers.txt diff --git a/debian/files b/debian/files new file mode 100644 index 0000000..2596e77 --- /dev/null +++ b/debian/files @@ -0,0 +1 @@ +dlife_0.0.12-1_alpha.deb misc optional diff --git a/debian/init.d b/debian/init.d new file mode 100644 index 0000000..2bc0fa6 --- /dev/null +++ b/debian/init.d @@ -0,0 +1,42 @@ +#! /bin/sh +# +# adapted from the dh_make template by Falk Hueffner +# +# 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 diff --git a/debian/postinst.debhelper b/debian/postinst.debhelper new file mode 100644 index 0000000..6d6c912 --- /dev/null +++ b/debian/postinst.debhelper @@ -0,0 +1,11 @@ +# 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 diff --git a/debian/postrm.debhelper b/debian/postrm.debhelper new file mode 100644 index 0000000..a7d2004 --- /dev/null +++ b/debian/postrm.debhelper @@ -0,0 +1,5 @@ +# Automatically added by dh_installinit +if [ "$1" = "purge" ] ; then + update-rc.d dlife remove >/dev/null +fi +# End automatically added section diff --git a/debian/prerm.debhelper b/debian/prerm.debhelper new file mode 100644 index 0000000..ad508d3 --- /dev/null +++ b/debian/prerm.debhelper @@ -0,0 +1,8 @@ +# 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 diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..2e3ef94 --- /dev/null +++ b/debian/rules @@ -0,0 +1,64 @@ +#!/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 diff --git a/debian/substvars b/debian/substvars new file mode 100644 index 0000000..e530b66 --- /dev/null +++ b/debian/substvars @@ -0,0 +1 @@ +shlibs:Depends=libc6.1 (>= 2.1.2-1) diff --git a/dlife.rc b/dlife.rc new file mode 100644 index 0000000..8b9328f --- /dev/null +++ b/dlife.rc @@ -0,0 +1,49 @@ +#!/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 + diff --git a/dlife.spec.in b/dlife.spec.in new file mode 100644 index 0000000..0c32c83 --- /dev/null +++ b/dlife.spec.in @@ -0,0 +1,91 @@ +# @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/ diff --git a/dlife_asm.pl b/dlife_asm.pl new file mode 100644 index 0000000..1a245c9 --- /dev/null +++ b/dlife_asm.pl @@ -0,0 +1,356 @@ +#!/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 () + { + # 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"; + } + } diff --git a/dlife_client.cron b/dlife_client.cron new file mode 100644 index 0000000..bd3cf16 --- /dev/null +++ b/dlife_client.cron @@ -0,0 +1,2 @@ +# Run the client to upload cells periodically. +5 * * * * dlife /usr/bin/dlife_client.pl diff --git a/dlife_client.pl.in b/dlife_client.pl.in new file mode 100644 index 0000000..bf34757 --- /dev/null +++ b/dlife_client.pl.in @@ -0,0 +1,397 @@ +#!/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 <) + { + 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 () + { + 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; + } diff --git a/dlife_disasm.pl b/dlife_disasm.pl new file mode 100755 index 0000000..a9c305e --- /dev/null +++ b/dlife_disasm.pl @@ -0,0 +1,147 @@ +#!/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 . +$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"; + } + diff --git a/dlife_server.pl.in b/dlife_server.pl.in new file mode 100644 index 0000000..9596888 --- /dev/null +++ b/dlife_server.pl.in @@ -0,0 +1,222 @@ +#!/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; + $_ = ; + + # 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 . on a line of its own.\r\n"; + + # Read in the cell. + my $cell = ""; + + while (length ($cell) < 8192) + { + alarm 10; + $_ = ; + 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 () + { + 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; + } diff --git a/dlink.h b/dlink.h new file mode 100644 index 0000000..2d4f061 --- /dev/null +++ b/dlink.h @@ -0,0 +1,146 @@ +/* DLIFE Copyright (C) 2000 Richard W.M. Jones + * 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 +#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 */ diff --git a/exec.c b/exec.c new file mode 100644 index 0000000..2f8b6a3 --- /dev/null +++ b/exec.c @@ -0,0 +1,556 @@ +/* DLIFE Copyright (C) 2000 Richard W.M. Jones + * 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 + +#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 diff --git a/god.dla b/god.dla new file mode 100644 index 0000000..467538e --- /dev/null +++ b/god.dla @@ -0,0 +1,90 @@ +;; 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. diff --git a/god.dlo b/god.dlo new file mode 100644 index 0000000..da9c6a2 --- /dev/null +++ b/god.dlo @@ -0,0 +1,56 @@ +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 diff --git a/image.c b/image.c new file mode 100644 index 0000000..ed632fd --- /dev/null +++ b/image.c @@ -0,0 +1,106 @@ +/* DLIFE Copyright (C) 2000 Richard W.M. Jones + * 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 +#include + +#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); +} diff --git a/image.h b/image.h new file mode 100644 index 0000000..d127a6b --- /dev/null +++ b/image.h @@ -0,0 +1,30 @@ +/* DLIFE Copyright (C) 2000 Richard W.M. Jones + * 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 */ diff --git a/index.html.in b/index.html.in new file mode 100644 index 0000000..9b31ff0 --- /dev/null +++ b/index.html.in @@ -0,0 +1,111 @@ + + + + + Distributed Artificial Life + + + +

Distributed Artificial Life

+ +

+ 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 ... +

+ +

News

+ +

Fri Apr 5 23:03:27 BST 2002

+ +

+ Version 1.0.0: Various fixes for Red Hat Linux 7.2. +

+ +

Mon Oct 16 23:11:13 BST 2000

+ +

+ Version 0.0.16: Added another patch from Falk + Hueffner which improves the Debian package + handling. +

+ +

Sat Oct 14 15:44:27 BST 2000

+ +

+ Version 0.0.15: Debian package (thanks to Falk Hueffner). + Client and soup processes now log status information to syslog. +

+ +

Download

+ +

+ All software is distributed under the terms of the + GNU General Public License (GPL). +

+ +

+ The latest version is @VERSION@, released @RELEASEDATE@. +

+ + + + + + + + + + + + + + + + + + + + + + +
Source code for client and server dlife-@VERSION@.tar.gz
Client: Binary RPM (for Red Hat, i686) dlife-@VERSION@-1.i686.rpm
Server: Binary RPM (for Red Hat, i686) dlife-server-@VERSION@-1.i686.rpm
Source RPM dlife-server-@VERSION@-1.src.rpm
Perl RPMs Various Perl RPMs which you may require ...
+ +

Patches from previous versions ...

+

Previous versions ...

+ +

Documentation

+ +
    +
  • DLIFE machine language reference
    + Documents the machine language implemented in the DLIFE + VM, the underlying philosophy, and how it differs from + the original Tierra machine language. +
  • DLIFE distributed architecture reference +
    + 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. +
+ +
+
rich@annexia.org
+ + +Last modified: Mon Oct 16 23:11:50 BST 2000 + + + diff --git a/install-sh b/install-sh new file mode 120000 index 0000000..e534836 --- /dev/null +++ b/install-sh @@ -0,0 +1 @@ +/usr/share/automake-1.4/install-sh \ No newline at end of file diff --git a/load.c b/load.c new file mode 100644 index 0000000..68b9128 --- /dev/null +++ b/load.c @@ -0,0 +1,116 @@ +/* DLIFE Copyright (C) 2000 Richard W.M. Jones + * 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 +#include +#include + +#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; +} diff --git a/load.h b/load.h new file mode 100644 index 0000000..9343cf3 --- /dev/null +++ b/load.h @@ -0,0 +1,29 @@ +/* DLIFE Copyright (C) 2000 Richard W.M. Jones + * 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 */ diff --git a/machineref.html b/machineref.html new file mode 100644 index 0000000..2ed3d98 --- /dev/null +++ b/machineref.html @@ -0,0 +1,746 @@ + + + + DLIFE machine language reference + + + +

DLIFE machine language reference

+ +

General overview

+ +

+ I'm going to assume that you're mostly familiar + with Tierra, + but I'll also give you a short introduction. +

+ +

+ 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. +

+ +

+ 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). +

+ +

+ 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. +

+ +

+ 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: +

+ +
+  code
+  : :
+  code
+  label 123
+  code
+  : :   <---
+  code
+  jump to label 123
+  code
+  : :
+  code
+
+ +

+ 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. +

+ +

+ Another important and unusual feature of the machine + language is that it allows cells to reproduce. Through + the use of the MALLOC and DIVIDE + instructions, a cell may produce a daughter cell, + populate it with code, and then divide (set it running + as an independent cell). +

+ +

+ 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 twice, 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. +

+ +

+ 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. +

+ +

+ Cells which execute instructions incorrectly (for + example, they do not fill the accumulator register + with a suitable value before calling MALLOC) + 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. +

+ +

+ 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. +

+ +

Cell virtual machine

+ +

+ The cell VM consists of 4 registers, some local + storage, a stack and stack pointer, an error counter + and possibly an attached daughter cell. +

+ +

Registers

+ +

+ The 4 visible registers are: +

+ + + + + + + + + + + + + + + + + +
Register Purpose
A The accumulator, for mathematical + operations and general purpose use.
B Base address, for addressing local variables.
I Index address.
P Program counter.
+ +

+ All registers are 16 bit signed integers, storing + any value between -32768 and 32767 inclusive. +

+ +

+ 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. +

+ +

+ When a cell is created, all registers are initialized + to zero. +

+ +

Local storage

+ +

+ 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 MALLOC. 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). +

+ +

+ 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. +

+ +

+ 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. +

+ +

+ After calling MALLOC, the I register is + initialized with the start address of the daughter + cell. Between the MALLOC and the next call + to DIVIDE, the cell may additionally write + to addresses I through I + A - 1, in order to initialize + the daughter. +

+ +

Stack

+ +

+ The cell has a stack of 16 words. Each stack entry is + a 16 bit signed integer. +

+ +

+ A stack pointer stores the current position in the + stack. +

+ +

+ The stack can only be accessed through one of the PUSH + or POP instructions. PUSH x (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. + POP x copies the value on the stack addressed + by the stack pointer into register x and decrements the + value of the stack pointer. +

+ +

+ 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. +

+ +

+ 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 PUSH or POP 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. +

+ +

+ When the cell is created, all stack entries and the stack + pointer are initialized to zero. +

+ +

Error counter

+ +

+ 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: +

+ +
    +
  • Incorrectly initializing the A register before + calling MALLOC. +
  • Not calling MALLOC before calling DIVIDE. +
  • Not calling DIVIDE before calling MALLOC. +
  • Executing FINDF or FINDB and not + finding a matching label. +
+ +

Basic instruction set

+ +

+ The basic instruction set consists of just 17 commands + encoded in just 38 different numeric values. +

+ +

+ Each instruction is encoded in a single byte. +

+ +

+ Two instructions, FINDB and FINDF + might be considered to be multi-byte instructions. + See the description below for details. +

+ +

+ There is one instruction prefix, IFZ, but + in the discussion below, we will just consider it + as if it was a single byte instruction (which, in + fact, it is). +

+ +

+ 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). +

+ +

+ Instructions are encoded into soup bytes as follows: +

+ +
+ 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)
+
+ +

+ The lower 6 bits are interpreted as follows: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Dec Hex Bin Mnemonic Meaning
0 00 00 0000 NOP0 No-op. This instruction does nothing when executed + but is used as a pattern matching label by FINDB + and FINDF.
1 01 00 0001 NOP1 No-op. This instruction does nothing when executed + but is used as a pattern matching label by FINDB + and FINDF.
2 02 00 0010 INC A A <- A + 1
3 03 00 0011 DEC A A <- A - 1
4 04 00 0100 SHL A A <- A << 1
7 07 00 0111 IFZ IFZ is normally used as an instruction + prefix, ie. IFZ <instruction>. + If A == 0, execute the next instruction, + otherwise skip the next instruction.
8 08 00 1000 FINDB FINDB should be followed by a pattern + (a series of one or more NOP0 and NOP1 bytes). The + FINDB instruction searches backwards + from the current program counter until it finds + the inverse 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. +
9 09 00 1001 FINDF FINDF should be followed by a pattern + (a series of one or more NOP0 and NOP1 bytes). The + FINDF instruction searches forwards + from the current program counter until it finds + the inverse 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. +
10 0A 00 1010 MALLOC MALLOC 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 MALLOC twice + without calling DIVIDE in between is an + error. Register A must be between 10 and 512. +
11 0B 00 1011 DIVIDE DIVIDE splits off the current daughter + cell and starts it running as a fully independent + cell. The daughter cell must first have been allocated + by MALLOC and populated with code, so + calling DIVIDE twice without calling + MALLOC in between is an error. +
12 0C 00 1100 MOVE [I],A Load the unsigned byte at relative address I into + register A. +
13 0D 00 1101 MOVE A,[I] 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. +
14 0E 00 1110 DMOVE [I],A Load the signed word (two bytes) at relative address I + into register A. The VM is big endian (Motorola ordering). +
15 0F 00 1111 DMOVE A,[I] 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). +
16-31 10-1F 01 r2r1 XOR <reg1>,<reg2> <reg2> <- <reg1> XOR <reg2> + for any registers in A (00), B (01), I (10) or P (11). +
32-35 20-23 10 00rr PUSH <reg> Push the register onto the stack for any + registers in A (00), B (01), I (10) or P (11). +
36-39 24-27 10 01rr POP <reg> Pop the top of the stack into the register for + any registers in A (00), B (01), I (10) or P (11). +
+ +

+ 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. +

+ +

Instruction set timings

+ +

+ This table shows the number of (virtual) CPU cycles + taken to execute each instruction. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Instruction Cycles Notes
NOP0 1
NOP1 1
INC A 1
DEC A 1
SHL A 1
IFZ 1
FINDB 1 + n ``n'' is the distance between the current + program counter and the start of the matched + pattern.
FINDF 1 + n ``n'' is the distance between the current + program counter and the start of the matched + pattern.
MALLOC 1
DIVIDE 1
MOVE [I],A 1
MOVE A,[I] 1
DMOVE [I],A 1
DMOVE A,[I] 1
XOR <reg1>,<reg2> 1
PUSH <reg> 1
POP <reg> 1
+ +

Instruction set macros

+ +

+ 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. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Macro Expands to Meaning Side effects?
Basic register operations ...
MOVE <reg1>,<reg2> PUSH <reg1>
POP <reg2>
Move the contents of register 1 into register 2. None.
SWAP <reg1>,<reg2> XOR <reg1>,<reg2>
+ XOR <reg2>,<reg1>
+ XOR <reg1>,<reg2>
+ XOR <reg2>,<reg1>
This has the effect of swapping the contents of + registers 1 and 2. None.
ZERO <reg> XOR <reg>,<reg> A <- 0 None.
ADD <n>, A INC A repeated n times. This is only + really suitable for small values of n. A <- A + n None.
MOVE <n>, A ZERO A followed by a series of + SHL A and INC A operations + required to initialize A to n. (n >= 0) A <- n None.
Access local (word-sized) variables, relative + to the base address register B ...
LOAD <n>, A PUSH I
MOVE B,A
ADD n*2,A
MOVE A,I
+ DMOVE [I],A
POP I
Load variable number n into register A. Destroys contents of I register.
STORE A,<n> PUSH I
PUSH A
MOVE B,A
ADD n*2,A
MOVE A,I
+ POP A
DMOVE A,[I]
POP I
Store register A in variable number n. Destroys contents of I register.
Jumps and subroutines ...
JMP I PUSH I
POP P
Jump to address I. None.
JMPF <pattern> FINDF <pattern>
PUSH I
POP P
Jump forwards to pattern. Destroys contents of I register.
JMPB <pattern> FINDB <pattern>
PUSH I
POP P
Jump backwards to pattern. Destroys contents of I register.
JMPZF <pattern> FINDF <pattern>
PUSH I
IFZ POP P
+ POP I
If A == 0, jump forwards to pattern. Destroys contents of I register.
JMPZB <pattern> FINDB <pattern>
PUSH I
IFZ POP P
+ POP I
If A == 0, jump backwards to pattern. Destroys contents of I register.
CALLF <pattern> PUSH P
FINDF <pattern>
PUSH I
POP P
Call forwards to a subroutine at pattern. The current + address is saved on the stack. Destroys contents of I register.
CALLB <pattern> PUSH P
FINDB <pattern>
PUSH I
POP P
Call backwards to a subroutine at pattern. The current + address is saved on the stack. Destroys contents of I register.
RET <n> POP A
ADD n+3,A
MOVE A,P
Return from subroutine. n is the length of the + pattern in the corresponding CALLF/CALLB + instruction. The return address should be the top + address on the stack. Destroys contents of A register.
Assembler directives ...
DB <n>   Define n bytes of scratch space. The scratch + space is initialized with 0xFF bytes (not + with zero bytes, since those clash with pattern symbols). None.
+ +

Patterns

+ +

+ The assembler recognizes patterns and writes out + a series of NOP0 and NOP1 bytes. +

+ + + + + + + + + + + + + + + + + + + + + +
Mnemonic Expands to
<pattern>: Each 0 and 1 in the pattern is translated into + a NOP0 and NOP1 on output.
~<pattern>: Each 0 and 1 in the pattern is translated into + a NOP1 and NOP0 on output (note the inversion).
instruction <pattern>: Each 0 and 1 in the pattern is translated into + a NOP0 and NOP1 on output.
instruction ~<pattern>: Each 0 and 1 in the pattern is translated into + a NOP1 and NOP0 on output (note the inversion).
+ +

+ Since the FINDB and FINDF patterns + search for the inverse of a pattern, a typical + instruction sequence will look like this: +

+ +
+0011:
+  ; : :
+  ; : :
+
+  FINDB ~0011
+  ; I contains address of 0011 pattern.
+
+ +
+
Richard Jones
+ + +Last modified: Sat Oct 7 13:49:42 BST 2000 + + + diff --git a/main.c b/main.c new file mode 100644 index 0000000..8122d7e --- /dev/null +++ b/main.c @@ -0,0 +1,483 @@ +/* DLIFE Copyright (C) 2000 Richard W.M. Jones + * 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 +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_STRING_H +#include +#endif + +#ifdef HAVE_PWD_H +#include +#endif + +#ifdef HAVE_GRP_H +#include +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#ifdef HAVE_SYSLOG_H +#include +#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 diff --git a/missing b/missing new file mode 120000 index 0000000..551440f --- /dev/null +++ b/missing @@ -0,0 +1 @@ +/usr/share/automake-1.4/missing \ No newline at end of file diff --git a/mkinstalldirs b/mkinstalldirs new file mode 120000 index 0000000..4b6a76d --- /dev/null +++ b/mkinstalldirs @@ -0,0 +1 @@ +/usr/share/automake-1.4/mkinstalldirs \ No newline at end of file diff --git a/params.h b/params.h new file mode 100644 index 0000000..1c74658 --- /dev/null +++ b/params.h @@ -0,0 +1,44 @@ +/* DLIFE Copyright (C) 2000 Richard W.M. Jones + * 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 */ diff --git a/random.c b/random.c new file mode 100644 index 0000000..6d11d23 --- /dev/null +++ b/random.c @@ -0,0 +1,50 @@ +/* DLIFE Copyright (C) 2000 Richard W.M. Jones + * 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 +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_TIME_H +#include +#endif + +#include "types.h" +#include "random.h" + +void +random_init () +{ +#if PERFECT_CPU + fprintf (stderr, "warning: PERFECT_CPU is defined in \n"); +#endif + + srandom (time (NULL)); +} diff --git a/random.h b/random.h new file mode 100644 index 0000000..988b1bc --- /dev/null +++ b/random.h @@ -0,0 +1,69 @@ +/* DLIFE Copyright (C) 2000 Richard W.M. Jones + * 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 + +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 */ diff --git a/servers.txt b/servers.txt new file mode 100644 index 0000000..9ad063e --- /dev/null +++ b/servers.txt @@ -0,0 +1,3 @@ +# Copy of servers.txt. + +server dlife.annexia.org eu uk diff --git a/soup.c b/soup.c new file mode 100644 index 0000000..fb4a4d5 --- /dev/null +++ b/soup.c @@ -0,0 +1,440 @@ +/* DLIFE Copyright (C) 2000 Richard W.M. Jones + * 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 +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_ASSERT_H +#include +#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; +} diff --git a/soup.conf b/soup.conf new file mode 100644 index 0000000..338cc72 --- /dev/null +++ b/soup.conf @@ -0,0 +1,65 @@ +# 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 diff --git a/soup.h b/soup.h new file mode 100644 index 0000000..e9cceed --- /dev/null +++ b/soup.h @@ -0,0 +1,79 @@ +/* DLIFE Copyright (C) 2000 Richard W.M. Jones + * 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 */ diff --git a/stamp-h.in b/stamp-h.in new file mode 100644 index 0000000..e69de29 diff --git a/state.c b/state.c new file mode 100644 index 0000000..fa7a8f1 --- /dev/null +++ b/state.c @@ -0,0 +1,67 @@ +/* DLIFE Copyright (C) 2000 Richard W.M. Jones + * 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 +#include + +#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); +} diff --git a/state.h b/state.h new file mode 100644 index 0000000..ce242b4 --- /dev/null +++ b/state.h @@ -0,0 +1,66 @@ +/* DLIFE Copyright (C) 2000 Richard W.M. Jones + * 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 */ diff --git a/types.h b/types.h new file mode 100644 index 0000000..504c633 --- /dev/null +++ b/types.h @@ -0,0 +1,43 @@ +/* DLIFE Copyright (C) 2000 Richard W.M. Jones + * 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 +#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 */ -- 1.8.3.1