changeset 12:478a2faf9119

The darn thing accidentally created a branch. I had to copy a half-dozen files to temporary locations to get them out of the way of the merge, and the next checkin will be putting them _back_. This commit is entirely to humor mercurial, and if I could figure out how to avoid getting it in this weird state, I would.
author Rob Landley <rob@landley.net>
date Wed, 01 Nov 2006 22:19:34 -0500
parents 66e7b6eaa2e2 (current diff) 8f8a8ac59c14 (diff)
children d87d8a056295
files
diffstat 10 files changed, 1581 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LICENSE	Wed Nov 01 22:19:34 2006 -0500
@@ -0,0 +1,280 @@
+		    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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile	Wed Nov 01 22:19:34 2006 -0500
@@ -0,0 +1,5 @@
+all:
+	$(CC) -Wall -Os -s $(CFLAGS) -I . main.c toys/*.c lib/*.c -o toybox
+
+clean:
+	rm toybox
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/functions.c	Wed Nov 01 22:19:34 2006 -0500
@@ -0,0 +1,270 @@
+/* vi: set sw=4 ts=4 :*/
+/* functions.c - reusable stuff.
+ *
+ * Functions with the x prefix are wrappers for library functions.  They either
+ * succeed or kill the program with an error message, but never return failure.
+ * They usually have the same arguments and return value as the function they
+ * wrap.
+ *
+ * Copyright 2006 Rob Landley <rob@landley.net>
+ */
+
+#include "toys.h"
+
+void verror_msg(char *msg, int err, va_list va)
+{
+	fprintf(stderr, "%s: ", toys.which->name);
+	vfprintf(stderr, msg, va);
+	if (err) fprintf(stderr, ": %s", strerror(err));
+	putc('\n', stderr);
+}
+
+void error_msg(char *msg, ...)
+{
+	va_list va;
+
+	va_start(va, msg);
+	verror_msg(msg, 0, va);
+	va_end(va);
+}
+
+void perror_msg(char *msg, ...)
+{
+	va_list va;
+
+	va_start(va, msg);
+	verror_msg(msg, errno, va);
+	va_end(va);
+}
+
+// Die with an error message.
+void error_exit(char *msg, ...)
+{
+	va_list va;
+
+	va_start(va, msg);
+	verror_msg(msg, 0, va);
+	va_end(va);
+
+	exit(toys.exitval);
+}
+
+// Die with an error message and strerror(errno)
+void perror_exit(char *msg, ...)
+{
+	va_list va;
+
+	va_start(va, msg);
+	verror_msg(msg, errno, va);
+	va_end(va);
+
+	exit(toys.exitval);
+}
+
+// Like strncpy but always null terminated.
+void strlcpy(char *dest, char *src, size_t size)
+{
+	strncpy(dest,src,size);
+	dest[size-1] = 0;
+}
+
+// Die unless we can allocate memory.
+void *xmalloc(size_t size)
+{
+	void *ret = malloc(size);
+	if (!ret) error_exit("xmalloc");
+
+	return ret;
+}
+
+// Die unless we can allocate prezeroed memory.
+void *xzalloc(size_t size)
+{
+	void *ret = xmalloc(size);
+	bzero(ret,size);
+	return ret;
+}
+
+// Die unless we can change the size of an existing allocation, possibly
+// moving it.  (Notice different arguments from libc function.)
+void xrealloc(void **ptr, size_t size)
+{
+	*ptr = realloc(*ptr, size);
+	if (!*ptr) error_exit("xrealloc");
+}
+
+// Die unless we can allocate a copy of this string.
+void *xstrndup(char *s, size_t n)
+{
+	void *ret = xmalloc(++n);
+	strlcpy(ret, s, n);
+	
+	return ret;
+}
+
+// Die unless we can allocate enough space to sprintf() into.
+char *xmsprintf(char *format, ...)
+{
+	va_list va;
+	int len;
+	char *ret;
+	
+	// How long is it?
+
+	va_start(va, format);
+	len = vsnprintf(0, 0, format, va);
+	len++;
+	va_end(va);
+
+	// Allocate and do the sprintf()
+	ret = xmalloc(len);
+	va_start(va, format);
+	vsnprintf(ret, len, format, va);	
+	va_end(va);
+
+	return ret;
+}
+
+// Die unless we can exec argv[] (or run builtin command).  Note that anything
+// with a path isn't a builtin, so /bin/sh won't match the builtin sh.
+void xexec(char **argv)
+{
+	toy_exec(argv);
+	execvp(argv[0], argv);
+	error_exit("No %s", argv[0]);
+}
+
+// Die unless we can open/create a file, returning file descriptor.
+int xopen(char *path, int flags, int mode)
+{
+	int fd = open(path, flags, mode);
+	if (fd == -1) error_exit("No file %s\n", path);
+	return fd;
+}
+
+// Die unless we can open/create a file, returning FILE *.
+FILE *xfopen(char *path, char *mode)
+{
+	FILE *f = fopen(path, mode);
+	if (!f) error_exit("No file %s\n", path);
+	return f;
+}
+
+// Read from file handle, retrying if interrupted.
+ssize_t reread(int fd, void *buf, size_t count)
+{
+	ssize_t len;
+	for (;;) {
+		len = read(fd, buf, count);
+		if (len >= 0  || errno != EINTR) return len;
+	}
+}
+
+// Keep reading until full or EOF
+ssize_t readall(int fd, void *buf, size_t count)
+{
+	size_t len = 0;
+	while (len<count) {
+		int i = reread(fd, buf, count);
+		if (!i) return len;
+		if (i<0) return i;
+		count += i;
+	}
+
+	return count;
+}
+
+// Die if we can't fill a buffer
+void xread(int fd, char *buf, size_t count)
+{
+	if (count != readall(fd, buf, count)) perror_exit("xread");
+}	
+
+char *xgetcwd(void)
+{
+	char *buf = getcwd(NULL, 0);
+	if (!buf) error_exit("xgetcwd");
+
+	return buf;
+}
+
+// Find this file in a colon-separated path.
+
+char *find_in_path(char *path, char *filename)
+{
+	char *next, *res = NULL, *cwd = xgetcwd();
+
+	while ((next = index(path,':'))) {
+		int len = next-path;
+
+		if (len==1) res = xmsprintf("%s/%s", cwd, filename);
+		else res = xmsprintf("%*s/%s",len-1,path,filename);
+		// Is there a file here we can execute?
+		if (!access(res, X_OK)) {
+			struct stat st;
+			// Confirm it's not a directory.
+			if (!stat(res, &st) && S_ISREG(st.st_mode)) break;
+		}
+		free(res);
+		res = NULL;
+	}
+	free(cwd);
+
+	return res;
+}
+
+// Convert unsigned int to ascii, writing into supplied buffer.  A truncated
+// result contains the first few digits of the result ala strncpy, and is
+// always null terminated (unless buflen is 0).
+void utoa_to_buf(unsigned n, char *buf, unsigned buflen)
+{
+	int i, out = 0;
+
+	if (buflen) {
+		for (i=1000000000; i; i/=10) {
+			int res = n/i;
+
+			if ((res || out || i == 1) && --buflen>0) {
+				out++;
+				n -= res*i;
+				*buf++ = '0' + res;
+			}
+		}
+		*buf = 0;
+	}
+}
+
+// Convert signed integer to ascii, using utoa_to_buf()
+void itoa_to_buf(int n, char *buf, unsigned buflen)
+{
+	if (buflen && n<0) {
+		n = -n;
+		*buf++ = '-';
+		buflen--;
+	}
+	utoa_to_buf((unsigned)n, buf, buflen);
+}
+
+// This static buffer is used by both utoa() and itoa(), calling either one a
+// second time will overwrite the previous results.
+//
+// The longest 32 bit integer is -2 billion plus a null terminator: 12 bytes.
+// Note that int is always 32 bits on any remotely unix-like system, see
+// http://www.unix.org/whitepapers/64bit.html for details.
+
+static char itoa_buf[12];
+
+// Convert unsigned integer to ascii, returning a static buffer.
+char *utoa(unsigned n)
+{
+	utoa_to_buf(n, itoa_buf, sizeof(itoa_buf));
+
+	return itoa_buf;
+}
+
+char *itoa(int n)
+{
+	itoa_to_buf(n, itoa_buf, sizeof(itoa_buf));
+
+	return itoa_buf;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/getmountlist.c	Wed Nov 01 22:19:34 2006 -0500
@@ -0,0 +1,45 @@
+/* vi: set sw=4 ts=4 : */
+/* getmountlist.c - Get a linked list of mount points, with stat information.
+ *
+ * Copyright 2006 Rob Landley <rob@landley.net>
+ */
+
+#include "toys.h"
+
+#include <mntent.h>
+
+char *path_mounts = "/proc/mounts";
+
+// Get a list of mount points from /etc/mtab or /proc/mounts, including
+// statvfs() information.  This returns a reversed list, which is good for
+// finding overmounts and such.
+
+struct mtab_list *getmountlist(int die)
+{
+	FILE *fp;
+	struct mtab_list *mtlist, *mt;
+	struct mntent me;
+	char evilbuf[2*PATH_MAX];
+
+	mtlist = 0;
+	if (!(fp = setmntent(path_mounts, "r"))) {
+		if (die) error_exit("cannot open %s", path_mounts);
+	} else {
+		while (getmntent_r(fp, &me, evilbuf, sizeof(evilbuf))) {
+			mt = xzalloc(sizeof(struct mtab_list) + strlen(me.mnt_fsname) +
+				strlen(me.mnt_dir) + strlen(me.mnt_type) + 3);
+			mt->next = mtlist;
+			// Get information about this filesystem.  Yes, we need both.
+			stat(me.mnt_dir, &(mt->stat));
+			statvfs(me.mnt_dir, &(mt->statvfs));
+			// Remember information from /proc/mounts
+			strcpy(mt->type, me.mnt_type);
+			mt->dir = mt->type + strlen(mt->type) + 1;
+			strcpy(mt->dir, me.mnt_dir);
+			mt->device = mt->dir + strlen(mt->dir) + 1;
+			strcpy(mt->device, me.mnt_fsname);
+			mtlist = mt;
+		}
+	}
+	return mtlist;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/lib.h	Wed Nov 01 22:19:34 2006 -0500
@@ -0,0 +1,51 @@
+/* vi: set ts=4 :*/
+/* lib.h - header file for lib directory
+ *
+ * Copyright 2006 Rob Landley <rob@landley.net>
+ */
+
+// functions.c
+void verror_msg(char *msg, int err, va_list va);
+void error_msg(char *msg, ...);
+void perror_msg(char *msg, ...);
+void error_exit(char *msg, ...);
+void perror_exit(char *msg, ...);
+void strlcpy(char *dest, char *src, size_t size);
+void *xmalloc(size_t size);
+void *xzalloc(size_t size);
+void xrealloc(void **ptr, size_t size);
+void *xstrndup(char *s, size_t n);
+char *xmsprintf(char *format, ...);
+void xexec(char **argv);
+int xopen(char *path, int flags, int mode);
+FILE *xfopen(char *path, char *mode);
+ssize_t reread(int fd, void *buf, size_t count);
+ssize_t readall(int fd, void *buf, size_t count);
+void xread(int fd, char *buf, size_t count);
+char *xgetcwd(void);
+char *find_in_path(char *path, char *filename);
+void utoa_to_buf(unsigned n, char *buf, unsigned buflen);
+void itoa_to_buf(int n, char *buf, unsigned buflen);
+char *utoa(unsigned n);
+char *itoa(int n);
+
+// llist.c
+void llist_free(void *list, void (*freeit)(void *data));
+
+struct string_list {
+	struct string_list *next;
+	char *str;
+};
+
+// getmountlist.c
+struct mtab_list {
+	struct mtab_list *next;
+	struct stat stat;
+	struct statvfs statvfs;
+	char *dir;
+	char *device;
+	char type[0];
+};
+
+struct mtab_list *getmountlist(int die);
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.c	Wed Nov 01 22:19:34 2006 -0500
@@ -0,0 +1,121 @@
+/* vi: set ts=4 :*/
+/* Toybox infrastructure.
+ *
+ * Copyright 2006 Rob Landley <rob@landley.net>
+ *
+ * Licensed under GPL version 2, see file LICENSE in this tarball for details.
+ */
+
+#include "toys.h"
+
+// The monster fun applet list.
+
+struct toy_list toy_list[] = {
+	// This one is out of order on purpose.
+	{"toybox", toybox_main, 0},
+	// The rest of these are alphabetical, for binary search.
+	{"cd", cd_main, TOYFLAG_NOFORK},
+	{"df", df_main, TOYFLAG_USR|TOYFLAG_SBIN},
+	{"exit", exit_main, TOYFLAG_NOFORK},
+	{"sh", toysh_main, TOYFLAG_BIN},
+	{"toysh", toysh_main, TOYFLAG_BIN}
+};
+
+#define TOY_LIST_LEN (sizeof(toy_list)/sizeof(struct toy_list))
+
+// global context for this applet.
+
+struct toy_context toys;
+
+struct toy_list *toy_find(char *name)
+{
+	int top, bottom, middle;
+
+	// If the name starts with "toybox", accept that as a match.  Otherwise
+	// skip the first entry, which is out of order.
+
+	if (!strncmp(name,"toybox",6)) return toy_list;
+	bottom = 1;
+
+	// Binary search to find this applet.
+
+	top = TOY_LIST_LEN-1;
+	for (;;) {
+		int result;
+		
+		middle = (top+bottom)/2;
+		if (middle<bottom || middle>top) return NULL;
+		result = strcmp(name,toy_list[middle].name);
+		if (!result) return toy_list+middle;
+		if (result<0) top=--middle;
+		else bottom = ++middle;
+	}
+}
+
+void toy_init(struct toy_list *which, char *argv[])
+{
+	// Free old toys contents here?
+
+	toys.which = which;
+	toys.argv = argv;
+	toys.exitval = 1;
+}
+
+// Run a toy.
+void toy_exec(char *argv[])
+{
+	struct toy_list *which;
+	
+	which = toy_find(argv[0]);
+	if (!which) return;
+
+	toy_init(which, argv);
+	
+	exit(toys.which->toy_main());
+}
+
+int toybox_main(void)
+{
+	static char *toy_paths[]={"usr/","bin/","sbin/",0};
+	int i, len = 0;
+
+	if (toys.argv[1]) {
+		if (toys.argv[1][0]!='-') {
+			toy_exec(toys.argv+1);
+			error_exit("No behavior for %s\n",toys.argv[1]);
+		}
+	}
+
+	// Output list of applets.
+	for (i=1; i<TOY_LIST_LEN; i++) {
+		int fl = toy_list[i].flags;
+		if (fl & TOYMASK_LOCATION) {
+			if (toys.argv[1]) {
+				int j;
+				for (j=0; toy_paths[j]; j++)
+					if (fl & (1<<j)) len += printf("%s", toy_paths[j]);
+			}
+			len += printf("%s ",toy_list[i].name);
+			if (len>65) {
+				putchar('\n');
+				len=0;
+			}
+		}
+	}
+	putchar('\n');
+	return 0;
+}
+
+int main(int argc, char *argv[])
+{
+	char *name;
+
+	// Figure out which applet to call.
+	name = rindex(argv[0], '/');
+	if (!name) name=argv[0];
+	else name++;
+	argv[0] = name;
+
+	toys.argv = argv-1;
+	return toybox_main();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/toys.h	Wed Nov 01 22:19:34 2006 -0500
@@ -0,0 +1,88 @@
+/* vi: set ts=4 :*/
+/* Toybox infrastructure.
+ *
+ * Copyright 2006 Rob Landley <rob@landley.net>
+ *
+ * Licensed under GPL version 2, see file LICENSE in this tarball for details.
+ */
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "lib/lib.h"
+
+int cd_main(void);
+int df_main(void);
+int exit_main(void);
+int toybox_main(void);
+int toysh_main(void);
+
+#define TOYFLAG_USR      (1<<0)
+#define TOYFLAG_BIN      (1<<1)
+#define TOYFLAG_SBIN     (1<<2)
+#define TOYMASK_LOCATION ((1<<4)-1)
+
+#define TOYFLAG_NOFORK   (1<<4)
+
+extern struct toy_list {
+	char *name;
+	int (*toy_main)(void);
+	int flags;
+} toy_list[];
+struct toy_list *toy_find(char *name);
+void toy_init(struct toy_list *which, char *argv[]);
+void toy_exec(char *argv[]);
+
+// Global context for this applet.
+
+extern struct toy_context {
+	struct toy_list *which;  // Which entry in toy_list is this one?
+	int exitval;             // Value error_exit feeds to exit()
+	int optflags;            // Command line option flags
+	char **argv;             // Command line arguments
+	char buf[4096];
+} toys;
+
+struct exit_data {;};
+struct cd_data {;};
+struct toybox_data {;};
+struct toysh_data {;};
+struct df_data {
+	struct string_list *fstype;
+	long units;
+};
+
+union toy_union {
+	struct exit_data exit;
+	struct cd_data cd;
+	struct toybox_data toybox;
+	struct toysh_data toysh;
+	struct df_data df;
+} toy;
+
+// Pending the addition of menuconfig...
+
+#define CFG_TOYS_FREE     0
+
+#define CFG_TOYSH_TTY     0  // Terminal control
+#define CFG_TOYSH_JOBCTL  0  // &, fg, bg, jobs.  ctrl-z with tty.
+#define CFG_TOYSH_FLOWCTL 0  // if, while, for, functions { }
+#define CFG_TOYSH_ENVVARS 0  // Environment variables
+#define CFG_TOYSH_LOCVARS 0  // Local, synthetic, fancy prompts, set, $?
+#define CFG_TOYSH_PIPES   0  // Pipes and redirects: | > < >> << && || & () ;
+
+#define CFG_DF_PEDANTIC   1  // Support -P and -k in df
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/toys/df.c	Wed Nov 01 22:19:34 2006 -0500
@@ -0,0 +1,125 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * df.c - report free disk space.
+ *
+ * Implemented roughly according to SUSv3:
+ * http://www.opengroup.org/onlinepubs/009695399/utilities/df.html
+ * 
+ * usage: df [-k] [-P|-t] [file...]
+ */
+
+#include "toys.h"
+
+static void show_mt(struct mtab_list *mt)
+{
+	int len;
+	long size, used, avail, percent;
+	uint64_t block;
+
+	// Return if it wasn't found (should never happen, but with /etc/mtab...)
+	if (!mt) return;
+
+	// If we have -t, skip other filesystem types
+	if (toy.df.fstype) {
+		struct string_list *sl;
+
+		for (sl = toy.df.fstype; sl; sl = sl->next)
+			if (!strcmp(mt->type, sl->str)) break;
+		if (!sl) return;
+	}
+
+	// If we don't have -a, skip synthetic filesystems
+	if (!(toys.optflags & 1) && !mt->statvfs.f_blocks) return;
+
+	// Figure out how much total/used/free space this filesystem has,
+	// forcing 64-bit math because filesystems are big now.
+	block = mt->statvfs.f_bsize ? : 1;
+
+	size = (long)((block * mt->statvfs.f_blocks) / toy.df.units);
+	used = (long)((block * (mt->statvfs.f_blocks-mt->statvfs.f_bfree))
+			/ toy.df.units);
+	avail = (long)((block
+				* (getuid() ? mt->statvfs.f_bavail : mt->statvfs.f_bfree))
+			/ toy.df.units);
+	percent = 100-(long)((100*(uint64_t)avail)/size);
+
+	// Figure out appropriate spacing
+	len = 25 - strlen(mt->device);
+	if (len < 1) len = 1;
+	if (CFG_DF_PEDANTIC && (toys.optflags & 8)) {
+		printf("%s %ld %ld %ld %ld%% %s\n", mt->device, size, used, avail,
+				percent, mt->dir);
+	} else {
+		printf("%s% *ld % 10ld % 9ld % 3ld%% %s\n",mt->device, len,
+			size, used, avail, percent, mt->dir);
+	}
+}
+
+int df_main(void)
+{
+	struct mtab_list *mt, *mt2, *mtlist;
+	char **argv;
+
+	// get_optflags("Pkt:a",&(toy.df.fstype));
+	argv = NULL;
+
+	// Handle -P and -k
+	toy.df.units = 1024;
+	if (CFG_DF_PEDANTIC && (toys.optflags & 8)) {
+		// Units are 512 bytes if you select "pedantic" without "kilobytes".
+		if ((toys.optflags&3) == 1) toy.df.units = 512;
+		printf("Filesystem %ld-blocks Used Available Capacity Mounted on\n",
+			toy.df.units);
+	} else puts("Filesystem\t1K-blocks\tUsed Available Use% Mounted on");
+
+	mtlist = getmountlist(1);
+
+	// If we have a list of filesystems on the command line, loop through them.
+	if (argv) {
+		char *next;
+
+		for(next = *argv; *next; next++) {
+			struct stat st;
+
+			// Stat it (complain if we can't).
+			if(!stat(next, &st)) {
+				perror_msg("`%s'", next);
+				toys.exitval = 1;
+				continue;
+			}
+
+			// Find and display this filesystem.  Use _last_ hit in case of
+			// -- bind mounts.
+			mt2 = NULL;
+			for (mt = mtlist; mt; mt = mt->next)
+				if (st.st_dev == mt->stat.st_dev) mt2 = mt;
+			show_mt(mt2);
+		}
+	} else {
+		// Get and loop through mount list.
+
+		for (mt = mtlist; mt; mt = mt->next) {
+			struct mtab_list *mt2, *mt3;
+
+			if (!mt->stat.st_dev) continue;
+
+			// Filter out overmounts.
+			mt3 = mt;
+			for (mt2 = mt->next; mt2; mt2 = mt2->next) {
+				if (mt->stat.st_dev == mt2->stat.st_dev) {
+					// For --bind mounts, take last match
+					if (!strcmp(mt->device, mt2->device)) mt3 = mt2;
+					// Filter out overmounts
+					mt2->stat.st_dev = 0;
+				}
+			}
+			show_mt(mt3);
+		}
+	}
+
+	if (CFG_TOYS_FREE) {
+		llist_free(mtlist, NULL);
+		free(argv);
+	}
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/toys/toysh.c	Wed Nov 01 22:19:34 2006 -0500
@@ -0,0 +1,214 @@
+/* vi: set sw=4 ts=4:
+ * 
+ * toysh - toybox shell
+ *
+ * Copyright 2006 Rob Landley <rob@landley.net>
+ *
+ * The spec for this is at:
+ * http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
+ *
+ * Although things like the bash man page are good to read too.
+ */
+
+// Handle embedded NUL bytes in the command line.
+
+#include "toys.h"
+
+// A single executable, its arguments, and other information we know about it.
+#define TOYSH_FLAG_EXIT    1
+#define TOYSH_FLAG_SUSPEND 2
+#define TOYSH_FLAG_PIPE    4
+#define TOYSH_FLAG_AND     8
+#define TOYSH_FLAG_OR      16
+#define TOYSH_FLAG_AMP     32
+#define TOYSH_FLAG_SEMI    64
+#define TOYSH_FLAG_PAREN   128
+
+// What we know about a single process.
+struct command {
+	struct command *next;
+	int flags;              // exit, suspend, && ||
+	int pid;                // pid (or exit code)
+	int argc;
+	char *argv[0];
+};
+
+// A collection of processes piped into/waiting on each other.
+struct pipeline {
+	struct pipeline *next;
+	int job_id;
+	struct command *cmd;
+	char *cmdline;         // Unparsed line for display purposes
+	int cmdlinelen;        // How long is cmdline?
+};
+
+// Parse one word from the command line, appending one or more argv[] entries
+// to struct command.  Handles environment variable substitution and
+// substrings.  Returns pointer to next used byte, or NULL if it
+// hit an ending token.
+static char *parse_word(char *start, struct command **cmd)
+{
+	char *end;
+
+	// Detect end of line (and truncate line at comment)
+	if (CFG_TOYSH_PIPES && strchr("><&|(;", *start)) return 0;
+
+	// Grab next word.  (Add dequote and envvar logic here)
+	end = start;
+	while (*end && !isspace(*end)) end++;
+	(*cmd)->argv[(*cmd)->argc++] = xstrndup(start, end-start);
+
+	// Allocate more space if there's no room for NULL terminator.
+
+	if (!((*cmd)->argc & 7))
+		xrealloc((void **)cmd,
+				sizeof(struct command) + ((*cmd)->argc+8)*sizeof(char *));
+	(*cmd)->argv[(*cmd)->argc] = 0;
+	return end;
+}
+
+// Parse a line of text into a pipeline.
+// Returns a pointer to the next line.
+
+static char *parse_pipeline(char *cmdline, struct pipeline *line)
+{
+	struct command **cmd = &(line->cmd);
+	char *start = line->cmdline = cmdline;
+
+	if (!cmdline) return 0;
+
+	if (CFG_TOYSH_JOBCTL) line->cmdline = cmdline;
+		
+	// Parse command into argv[]
+	for (;;) {
+		char *end;
+		
+		// Skip leading whitespace and detect end of line.
+		while (isspace(*start)) start++;
+		if (!*start || *start=='#') {
+			if (CFG_TOYSH_JOBCTL) line->cmdlinelen = start-cmdline;
+			return 0;
+		}
+
+		// Allocate next command structure if necessary
+		if (!*cmd) *cmd = xzalloc(sizeof(struct command)+8*sizeof(char *));
+
+		// Parse next argument and add the results to argv[]
+		end = parse_word(start, cmd);
+
+		// If we hit the end of this command, how did it end?
+		if (!end) {
+			if (CFG_TOYSH_PIPES && *start) {
+				if (*start==';') {
+					start++;
+					break;
+				}
+				// handle | & < > >> << || &&
+			}
+			break;
+		}
+		start = end;
+	}
+
+	if (CFG_TOYSH_JOBCTL) line->cmdlinelen = start-cmdline;
+
+	return start;
+}
+
+// Execute the commands in a pipeline
+static void run_pipeline(struct pipeline *line)
+{
+	struct toy_list *tl;
+	struct command *cmd = line->cmd;
+	if (!cmd || !cmd->argc) return;
+
+	tl = toy_find(cmd->argv[0]);
+	// Is this command a builtin that should run in this process?
+	if (tl && (tl->flags & TOYFLAG_NOFORK)) {
+		struct toy_list *which = toys.which;
+		char **argv = toys.argv;
+
+		toy_init(tl, cmd->argv);
+		cmd->pid = tl->toy_main();
+		toy_init(which, argv);
+	} else {
+		int status;
+
+		cmd->pid = vfork();
+		if (!cmd->pid) xexec(cmd->argv);
+		else waitpid(cmd->pid, &status, 0);
+
+		if (CFG_TOYSH_FLOWCTL || CFG_TOYSH_PIPES) {
+			if (WIFEXITED(status)) cmd->pid = WEXITSTATUS(status);
+			if (WIFSIGNALED(status)) cmd->pid = WTERMSIG(status);
+		}
+	}
+
+	return;
+}
+
+// Free the contents of a command structure
+static void free_cmd(void *data)
+{
+	struct command *cmd=(struct command *)data;
+
+	while(cmd->argc) free(cmd->argv[--cmd->argc]);
+}
+
+
+// Parse a command line and do what it says to do.
+static void handle(char *command)
+{
+	struct pipeline line;
+	char *start = command;
+
+	// Loop through commands in this line
+
+	for (;;) {
+
+		// Parse a group of connected commands
+
+		memset(&line,0,sizeof(struct pipeline));
+		start = parse_pipeline(start, &line);
+		if (!line.cmd) break;
+
+		// Run those commands
+
+		run_pipeline(&line);
+		llist_free(line.cmd, free_cmd);
+	}
+}
+
+int cd_main(void)
+{
+	char *dest = toys.argv[1] ? toys.argv[1]: getenv("HOME");
+	if (chdir(dest)) error_exit("chdir %s",dest);
+	return 0;
+}
+
+int exit_main(void)
+{	
+	exit(toys.argv[1] ? atoi(toys.argv[1]) : 0);
+}
+
+int toysh_main(void)
+{
+	char *command=NULL;
+	FILE *f;
+
+	// TODO get_optflags(argv, "c:", &command);
+
+	f = toys.argv[1] ? xfopen(toys.argv[1], "r") : NULL;
+	if (command) handle(command);
+	else {
+		unsigned cmdlen=0;
+		for (;;) {
+			if (!f) putchar('$');
+			if (1 > getline(&command, &cmdlen, f ? : stdin)) break;
+			handle(command);
+		}
+		if (CFG_TOYS_FREE) free(command);
+	}
+		
+	return 1;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/www/license.html	Wed Nov 01 22:19:34 2006 -0500
@@ -0,0 +1,382 @@
+<!--#include file="header.html" -->
+
+<h2>Toybox is licensed under the terms of GPLv2.</h2>
+
+<p>The complete text of the General Public License version 2 is included in the
+file LICENSE in each source tarball.  Version 2 is the only version of
+this license which toybox is distributed under.  (I.E. It doesn't have the
+strange "or later" dual license some projects have.)</p>
+
+<h2>Clarifications</h2>
+
+<p>The GPL is a bit old and crufty in places, but it's still the best open
+source license there is, and lots of source code (like the Linux kernel) is
+distributed under it.  Lots of de facto interpretations have sprung up to deal
+with things like the fact that it predates the internet service provider
+industry.  Nothing in the rest of this page changes the actual license, so you
+can ignore the rest of this page if you're happy with a strict reading of
+GPLv2.  But just to be clear, here's how the authors of this project are
+interpreting the sucker where it says something stupid.</p>
+
+<p>Section 1: <b>You have permission to rephrase the license notice on
+individual source files.</b>  This doesn't mean you can change what license the
+code is under, or that you can remove other people's copyright notices.  You
+certainly can't change the test of the GPL itself.  What it means is that if
+you use this code in a project that distributes source in zip files instead of
+tarballs, or your package's copy of the GPLv2 text isn't in a file called
+"LICENSE", it's silly to preserve an obsolete notice verbatim and add some
+kind of "correction" after the old notice.</p>
+
+<p>Some lawyers seem to think a strict reading of GPLv2 section 1 (and later
+sections including section 1 by reference) requires maintaining old notices in
+perpetuity.  Even if you had code that used to be dual licensed, but created
+a derived work that's just under one of the two licenses, so the old license
+notice is not just strange or misleading but actually incorrect for the new
+file.  (For example, splicing GPLv2 only code into a dual "GPLv2 or later"
+project produces a result that can be distributed under the terms of GPLv2,
+but not GPLv3.  The result cannot be distributed under the "or later" part,
+so a license notice saying it could is factually wrong.)</p>
+
+<p>I don't know if we're ever going to put any dual licensed code into the tree,
+but I want to head that one off now.  The actual license text is the important
+thing, the per-file notice is a courtesy.</p>
+
+<p>Section 2: <b>We don't put the change history in comments in the source
+code, we put it in our source control system.</b>  We have source control for a
+reason.  That's where this information belongs, and that's where we put it.
+It's world readable on the web, and you can download a snapshot of the whole
+repository if you like.  The GPL predates modern source control systems, but
+this project does not.</p>
+
+<p>Section 3: <b>We distribute source code through the internet.</b>  If
+your "written offer" includes a URL, and the source code remains anonymously
+downloadable at that location for three years after you stop distributing
+binaries, life is good as far as we're concerned.  (No, you can't encrypt it,
+or require a login, or otherwise be slimy bastards acting in bad faith.  We'll
+come after you if you're not satisfying the terms of the license, this is just
+talking about how you can satisfy those terms without having to mail physical
+media.  Most people are already doing it this way.)</p>
+
+<p>Also, <a href="http://software.newsforge.com/article.pl?sid=06/06/23/1728205&tid=150">what the FSF did to Mepis</a> was inexcusable.  (Further discussed
+in <a href="http://www.busybox.net/lists/busybox/2006-June/022797.html">this
+thread</a>.)  Mepis partnered with Ubuntu, put out a press release quoting
+Ubuntu's founder about how cool the partnership was, and then pointed to
+Ubuntu's source repository for packages it was using unmodified Ubuntu versions
+of.  As far as we're concerned, Mepis didn't do anything wrong, and the FSF
+was a bully.  The FSF was wrong when it tried to make an example out of a
+company that was acting in good faith.</p>
+
+<p>To make sure the FSF doesn't pick on anyone else against our wishes, we're
+clarifying that if you didn't modify the source code, and the binaries you're
+distributing can be entirely regenerated from a public upstream source,
+pointing to that upstream source in good faith is good enough for us, as long
+as they don't mind the extra bandwidth and the correct source code stays
+available at that location for the duration of your responsiblity to
+redistribute source.</p>
+
+<p>This doesn't mean it's fair for a Fortune 500 company to point millions of
+people at somebody's home DSL line (certainly not without asking first).
+And if the source that's available there isn't the complete source you used
+to produce your binaries, you haven't fulfilled your obligations either.
+And if the code stops being available at that location, you're not off the
+hook and have to find a new location or put up your own mirror.  And obviously
+it has to be the _right_ source code (if you modified it, we want the patch,
+and claiming you didn't modify it when you actually did is fraud).</p>
+
+<p>This is not a "get out of jail free" card: It's still your responsibility to
+make the source available.  We're just saying you can reasonably delegate to
+something like Sourceforge or ibilbio and as long as everyone who wants the
+source can get it, we're happy.  If the site you point to objects or goes down,
+responsibility obviously reverts to you.</p>
+
+<p>But if this project needs mirrors, we'll _ask_.  (Most likely we'll ask
+someone like sourceforge, OSL, ISC, ibiblio, archive.org...)</p>
+
+<p>Section 9: <b>Does not apply to this project.</b>  We're specifying the
+version, it's version 2.  There is no "or later versions" clause to require
+interpreting.
+
+<hr>
+<pre>
+		    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
+</pre>
+<!--#include file="footer.html" -->