diff options
-rw-r--r-- | LICENSE | 280 | ||||
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | lib/functions.c | 270 | ||||
-rw-r--r-- | lib/getmountlist.c | 45 | ||||
-rw-r--r-- | lib/lib.h | 51 | ||||
-rw-r--r-- | main.c | 121 | ||||
-rw-r--r-- | toys.h | 88 | ||||
-rw-r--r-- | toys/df.c | 125 | ||||
-rw-r--r-- | toys/toysh.c | 214 | ||||
-rw-r--r-- | www/license.html | 382 |
10 files changed, 1581 insertions, 0 deletions
diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..5a965fbc --- /dev/null +++ b/LICENSE @@ -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 diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..ad695e32 --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +all: + $(CC) -Wall -Os -s $(CFLAGS) -I . main.c toys/*.c lib/*.c -o toybox + +clean: + rm toybox diff --git a/lib/functions.c b/lib/functions.c new file mode 100644 index 00000000..44f21b55 --- /dev/null +++ b/lib/functions.c @@ -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; +} diff --git a/lib/getmountlist.c b/lib/getmountlist.c new file mode 100644 index 00000000..8410a923 --- /dev/null +++ b/lib/getmountlist.c @@ -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; +} diff --git a/lib/lib.h b/lib/lib.h new file mode 100644 index 00000000..28888a49 --- /dev/null +++ b/lib/lib.h @@ -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); + @@ -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(); +} @@ -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 diff --git a/toys/df.c b/toys/df.c new file mode 100644 index 00000000..cbebd157 --- /dev/null +++ b/toys/df.c @@ -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; +} diff --git a/toys/toysh.c b/toys/toysh.c new file mode 100644 index 00000000..7ac430c9 --- /dev/null +++ b/toys/toysh.c @@ -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; +} diff --git a/www/license.html b/www/license.html new file mode 100644 index 00000000..c178a96d --- /dev/null +++ b/www/license.html @@ -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" --> |