Anonymous | Login | 2024-11-13 16:14 UTC |
Main | My View | View Issues | Change Log | Docs |
Viewing Issue Simple Details [ Jump to Notes ] | [ Issue History ] [ Print ] | |||||||||||
ID | Category | Severity | Type | Date Submitted | Last Update | |||||||
0001861 | [1003.1(2024)/Issue8] Shell and Utilities | Objection | Error | 2024-10-11 12:32 | 2024-10-31 15:29 | |||||||
Reporter | stephane | View Status | public | |||||||||
Assigned To | ||||||||||||
Priority | normal | Resolution | Accepted As Marked | |||||||||
Status | Interpretation Required | |||||||||||
Name | Stephane Chazelas | |||||||||||
Organization | ||||||||||||
User Reference | ||||||||||||
Section | xargs utility | |||||||||||
Page Number | 3601 | |||||||||||
Line Number | 123207-123214 | |||||||||||
Interp Status | Proposed | |||||||||||
Final Accepted Text | Note: 0006934 | |||||||||||
Summary | 0001861: xargs -L broken by 0000243 resolution | |||||||||||
Description |
Between the 2018 and the 2024 editions, the description of the -L option changed from: -L number [XSI] The utility shall be executed for each non-empty number <strong>lines of arguments</strong> from standard input. The last invocation of utility shall be with fewer lines of arguments if fewer than number remain. A line is considered to end with the first <newline> unless the last character of the line is an unescaped <blank>; a trailing unescaped <blank> signals continuation to the next non-empty line, inclusive. To: -L number [XSI] Invoke utility for each set of <strong>number arguments</strong> from standard input. The last invocation of utility shall be with fewer arguments if fewer than number remain. If the -0 option is not specified, each line in the standard input shall be treated as containing one argument except that empty lines shall be ignored and a line ending with a trailing unescaped <blank> shall signal continuation to the next non-empty line, inclusive; such continuation shall result in removal of all trailing unescaped <blank> characters and all <newline> characters that immediately follow them from the argument. (<strong>emphasis</strong> mine). 0000243 was about adding -0, it had no business changing the behaviour of -L so radically. -Ln is to get arguments from n lines, not to treat n lines as one argument each. On an input like: a "b c" d e\ f g xargs -L1 cmd Is meant to call cmd 3 times, once with "a", "b c" and "d" as arguments, once with "e f" and once with "g" |
|||||||||||
Desired Action | Revert the wording not related to "-0" to that of the 2018 edition. | |||||||||||
Tags | tc1-2024 | |||||||||||
Attached Files | ||||||||||||
|
Relationships | |||||||||||||
|
Notes | |
(0006913) stephane (reporter) 2024-10-11 16:28 |
Actually, it looks like the combination of -0 and -L is not really covered in the 0000243 resolution, it should probably be: << If -0 is specified, -L number is equivalent to -n number, if not [insert 2018 edition text:] The utility shall be executed for each non-empty number lines of arguments from standard input. The last invocation of utility shall be with fewer lines of arguments if fewer than number remain. A line is considered to end with the first <newline> unless the last character of the line is an unescaped <blank>; a trailing unescaped <blank> signals continuation to the next non-empty line, inclusive >> In: << Fewer arguments shall be used if - The command line length accumulated exceeds the size specified by the -s option (or {LINE_MAX} if there is no -s option). >> In the description of -n, the "(or {LINE_MAX} if there is no -s option)" is very undesirable, and I haven't found a xargs implementation that honours that, with or without -0 (I tried GNU, FreeBSD, toybox, busybox, ast-open, heirloom toolchest (meant to be derived from Solaris 8 IIRC, none of which truncated the command line to LINE_MAX bytes in my tests). That might be worth addressing at the same time. |
(0006914) stephane (reporter) 2024-10-12 05:57 |
For the record, AFAIK, -L is a POSIX invention. The original was -l, likely from SunOS (also found on GNU), except the number is optional for -l which is likely why POSIX didn't specify it (like for -I, -E). The 2018 text closely resembles that of the SunOS man page from the 80s. In any case, I would agree that being able to take arguments from whole lines of input, verbatim, is badly missing, but that's not what -l/-L are about. For that, see the -d '\n' option of GNU xargs (which can be combined with -n, -L, -I...) |
(0006916) geoffclare (manager) 2024-10-14 16:13 |
> For the record, AFAIK, -L is a POSIX invention. To set the record straight, I'll point out that -L is marked XSI. It found its way into POSIX from SUSv2 when POSIX.1, POSIX.2, and SUS were merged to form POSIX.1-2001 / SUSv3. It first appeared in XPG4. XPG3 had -l and no -L; XPG4 marked -l obsolescent and added -L. Obviously this change was influenced by POSIX.2's utility syntax guidelines (the XPG alignment with POSIX.2 happened between XPG3 and XPG4), but that's not the same as -L being "a POSIX invention". > The 2018 text closely resembles that of the SunOS man page from the 80s. Most likely the SunOS man page text and the XPG3 text were both based on the wording for -l in SVID. |
(0006917) stephane (reporter) 2024-10-15 05:09 edited on: 2024-10-15 05:23 |
Re: Note: 0006916 Thanks for setting me straight on XPG vs POSIX and also on the origin of -l. Not sure how, but I had come to the erroneous conclusion that -l was not in SysV, but it was there indeed and in SysIII and in the original xargs implementation in PWB Unix from the late 70s. Not on BSDs. The SysIII man page had: -lnumber Command is executed for each non-empty number lines of arguments from standard input. The last invoca‐ tion of command will be with fewer lines of argu‐ ments if fewer than number remain. A line is con‐ sidered to end with the first new-line unless the last character of the line is a blank or a tab; a trailing blank/tab signals continuation through the next non-empty line. If number is omitted 1 is as‐ sumed. Option -x is forced. |
(0006918) geoffclare (manager) 2024-10-17 09:08 edited on: 2024-10-24 16:01 |
OLD Interpretation response ------------------------ The standard states that xargs -L number utility invokes utility for for each set of number arguments from standard input, and conforming implementations must conform to this. However, concerns have been raised about this which are being referred to the sponsor. Rationale: ------------- When the -0 option was added, there was no intention to change the behavior of -L when -0 is not specified, but an attempt to reword the description of -L in a way that covered both cases resulted in such a change. Notes to the Editor (not part of this interpretation): ------------------------------------------------------- On page 3601 line 123207 section xargs (-L), change: Invoke utility for each set of number arguments from standard input. The last invocation of utility shall be with fewer arguments if fewer than number remain. If the -0 option is not specified, each line in the standard input shall be treated as containing one argument except that empty lines shall be ignored and a line ending with a trailing unescaped <blank> shall signal continuation to the next non-empty line, inclusive; such continuation shall result in removal of all trailing unescaped <blank> characters and all <newline> characters that immediately follow them from the argument.to: If the -0 option is specified, -L number shall be equivalent to -n number. If the -0 option is not specified, the utility shall be invoked for each non-empty number logical lines of arguments from standard input. The last invocation of utility shall be with fewer logical lines of arguments if fewer than number remain. Each line in the standard input shall be treated as one logical line except that empty lines shall be ignored and a line ending with a trailing unescaped <blank> shall signal continuation of the logical line to the next non-empty line, inclusive; such continuation shall result in removal of all trailing unescaped <blank> characters and all <newline> characters that immediately follow them from the logical line. On page 3601 line 123218 section xargs (-n), change: (or {LINE_MAX} if there is no -s option)to: (or the default command line length if there is no -s option) |
(0006921) agadmin (administrator) 2024-10-17 16:25 |
Interpretation proposed: 17 October 2024 |
(0006922) stephane (reporter) 2024-10-18 06:34 edited on: 2024-10-20 19:58 |
Thanks for the quick resolution. An extra change IMO worth applying and that was not mentioned in my original request: I'd change: find . -type f -print0 | xargs -0 -p -L 1 ar -r arch to: find . -type f -print0 | xargs -r -0 -p -n 1 ar -r arch That is: 1. (unrelated) add -r so ar be not called with no file argument if no regular file is found. 2. Change -n to -L which would be more canonical. -L suggests "Line" which is confusing with -0, where -L is an alias for -n for no better meaning to give to it there. It would probably be worth giving an example showing the difference between -n and -L given so many people are confused about them (and many also wrongly assume xargs works with lines in general). Maybe something like: xargs -L2 sh -c 'IFS=,; printf "%d: <%s>\n" "$#" "$*"' sh <&l t; 'EOF' a b "\\ c //" d e f g EOF Where that inline sh script is passed the arguments from 2 lines at a time giving: 5: <a,b,\\ c //,d,e> 2: <f,g> To be compared with: xargs -n2 sh -c 'IFS=,; printf "%d: <%s>\n" "$#" "$*"' sh <&l t; 'EOF' a b "\\ c //" d e f g EOF Where the script is passed 2 arguments at a time regardless of which lines those come from, giving: 2: <a,b> 2: <\\ c //,d> 2: <e,f> 1: <g> |
(0006923) stephane (reporter) 2024-10-18 07:02 |
Also, maybe that would warrant a separate bug, but what happens when the arg size limit is reached within the -L n lines (without -0) is not very clear. The -s option description only /suggests/ that lines should not be broken apart, as in with -s1000 -L2, if the args from 2 lines don't fit in the 1000 byte limit, pass the args from 1 line instead. GNU xargs seems to just return an error instead in that case. Actually, in that regard, for GNU xargs, contrary to what I suggested and has now been included in the proposed resolution, xargs -0 -L "$number" is not equivalent to xargs -0 -n "$number" because with the former if $number arguments don't fit in the -s limit, an error is returned, while in the latter, fewer arguments are used if possible instead. I cannot test other implementations at the moment to check whether that's a widespread behaviour. |
(0006924) stephane (reporter) 2024-10-18 07:08 edited on: 2024-10-18 07:10 |
GNU xargs does document that -L implies -x, so -0L "$number" is more like -0xn "$number" at least there. |
(0006925) geoffclare (manager) 2024-10-18 08:39 |
Re: Note: 0006923 GNU differs from Solaris when -s and -L are used together: GNU $ printf '1234567890\n1234567890\n' | xargs -L 2 -s 20 echo xargs: argument list too long Solaris $ printf '1234567890\n1234567890\n' | xargs -L 2 -s 20 echo 1234567890 1234567890 $ printf '1234567890\n1234567890\n' | xargs -x -L 2 -s 20 echo xargs: Argument list too long Seems odd that GNU would take away the user's ability to choose whether they want -x to be in effect or not with -L. As it happens, the behaviour of -x was recently the subject of bug 0001853 and its resolution requires the Solaris behaviour here. |
(0006927) stephane (reporter) 2024-10-19 20:56 |
GNU's xargs has been documenting that -L (formerly -l) implies -x at least since 3.1 in 1991 which is the oldest version I could find. Even if not documented, FreeBSD and NetBSD's xargs behave like GNU here They both have: if (Iflag || Lflag) xflag = 1; And have had since -L was added there (in 2002 and 2007 respectively). For those where -L doesn't imply -x, in xargs -L "$lines" -s "$size" cmd if the arg list from $lines lines doesn't fit within $size, there's the question of whether cmd is called with arguments from fewer lines, or just fewer arguments, including possibly a subset of the arguments on the last line, and if the latter, for the next run, whether it starts picking arguments from the next line, or from where it left in the unfinished line from the previous run. For instance on an input like: 00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 Would xargs -L2 -s 23 echo + output: + 00001 00002 00003 + 00004 00005 00006 + 00007 00008 00009 + 00010 00011 00012 (using one line when 2 lines don't fit within the 23 byte limit) Or: + 00001 00002 00003 00004 + 00007 00008 00009 00010 (still be line based, but discarding 5, 6, 11, 12) Or: + 00001 00002 00003 00004 + 00005 00006 00007 00008 + 00009 00010 00011 00012 And not be really line based at all. I don't have access to a Solaris machine any longer, so I can't test there. |
(0006928) gbrandenrobinson (reporter) 2024-10-19 21:10 |
Re: note 6927 On the FSF's compiler farm's Solaris 10 box, I get this: bash-3.2$ type xargs xargs is /usr/bin/xargs bash-3.2$ cat | xargs -L2 -s 23 echo + 00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 + 00001 00002 + 00003 00004 + 00005 00006 + 00007 00008 + 00009 00010 + 00011 00012 The Solaris 11 machine handled terminal I/O a bit more noisily, so I modified my approach, but produced the same results. -bash-4.4$ printf '00001 00002 00003\n00004 00005 00006\n00007 00008 00009\n00010 00011 00012\n' | xargs -L2 -s 23 echo + + 00001 00002 + 00003 00004 + 00005 00006 + 00007 00008 + 00009 00010 + 00011 00012 |
(0006929) stephane (reporter) 2024-10-20 07:24 |
Sorry, I had intended that 23 bytes to be big enough for one line but not for two, but that was too simplistic and I should have tested it before posting. What the execve() limit is the limit of varies from system to system (and even version thereof), but even with the POSIX definition where it's on the size in bytes of all args (and args only, not the environment variables) including a NUL delimiter, those 23 bytes were not big enough for even echo + 00001 00002 00003 which is 5+2+6+6+6 = 25. Testing with ast-open's xargs on GNU/Linux, I see its -s size seems to be taking the environment into account and also possibly the size of the argv[] and envp[] arrays of pointers. Without -L: $ print -raC3 {00001..00012} # (zsh) 00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 $ print -aC3 {00001..00012} | ast-open/xargs -s5040 echo + + 00001 00002 00003 00004 + 00005 00006 00007 00008 + 00009 00010 00011 00012 (it also seems to run a builtin echo, not the system's echo utility). But its -L seems to work like -n there. Without a -s "$size": $ print -raC3 {00001..00012} | ast-open/xargs -L2 00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 $ ast-open/xargs --version version xargs (AT&T Research) 2012-04-11 Given it's the same output as with your Solaris test, it could be that it correctly breaks the list into "echo + 00001 00002" so as to fit into those 23 bytes and ignore line boundaries or that it is broken in a similar way as ast-open's one, so the test is not fully conclusive unforunately. In any case, while Geoff has a point that even with -L, it would be nice to let the user decide whether -x applies or not, the behaviour without is potentially surprising and I can't think of a use case where it would be desirable. So it does also make sense to me for -x to be the default. In any case, it seems to me it would be too late to forbid the GNU/FreeBSD/NetBSD behaviour in the POSIX specification now. |
(0006930) stephane (reporter) 2024-10-20 08:25 |
Re: Note: 0006929 > In any case, it seems to me it would be too late to forbid the GNU/FreeBSD/NetBSD behaviour in the POSIX specification now. Seems it's also the case of macos' xargs (https://github.com/apple-oss-distributions/shell_cmds/blob/shell_cmds-319.0.1/xargs/xargs.c#L292) [^] and OpenBSD's (https://github.com/openbsd/src/blob/master/usr.bin/xargs/xargs.c#L184), [^] so we can reasonably suppose it's going to be the same on all BSDs. Neither busybox nor toybox have -L AFAICT. On AIX https://www.ibm.com/docs/en/aix/7.3?topic=x-xargs-command [^] documents that -l implies -x. It's not clear whether that applies to -L as well. With the heirloom toolchest, meant to be derived from OpenSolaris, built on GNU/Linux: $ print -aC3 {00001..12} | heirloom/xargs -s30 -L2 00001 00002 00003 00004 00005 xargs: arg list too long |
(0006931) stephane (reporter) 2024-10-21 06:20 |
Re: Note: 0006930 > On AIX https://www.ibm.com/docs/en/aix/7.3?topic=x-xargs-command [^] [^] > documents that -l implies -x. It's not clear whether that applies to -L as > well. D'oh, like in SysIII as quoted above. SUSv2 did also say that -l implies -x, but (more clearly than AIX) not -L, though didn't specify what happened when the -s limit is reached. HP/UX man page has similar wording as in SUSv2. BTW, may be worth noting that: find . -type f -print0 | xargs -r -0 -p -n 1 ar -r arch is more or less equivalent (except potentially for the overall exit status) to: find . -type f -ok ar -r arch {} ';' (might be worth adding a ! -path ./arch as well). |
(0006932) geoffclare (manager) 2024-10-21 09:01 edited on: 2024-10-21 09:02 |
> it could be that [Solaris] correctly breaks the list into "echo + 00001 00002" so as to fit into those 23 bytes and ignore line boundaries or that it is broken in a similar way as ast-open's one Without -s, Solaris handles lines as expected, so not broken like ast-open's xargs: $ printf '00001 00002 00003\n00004 00005 00006\n00007 00008 00009\n00010 00011 00012\n' | xargs -L 2 echo + + 00001 00002 00003 00004 00005 00006 + 00007 00008 00009 00010 00011 00012 Experimenting with different -s limits, it seems it will carry args forward to the next line: $ printf '00001 00002 00003\n00004 00005 00006\n00007 00008 00009\n00010 00011 00012\n' | xargs -L 2 -s 36 echo + + 00001 00002 00003 00004 + 00005 00006 00007 00008 + 00009 00010 00011 00012 but in some situations will also end an argument set at the end of a line: $ printf '00001 00002 00003\n00004 00005 00006\n00007 00008 00009\n00010 00011 00012\n' | xargs -L 2 -s 40 echo + + 00001 00002 00003 00004 00005 + 00006 00007 00008 00009 + 00010 00011 00012 > In any case, it seems to me it would be too late to forbid the GNU/FreeBSD/NetBSD behaviour in the POSIX specification now. I agree, it should be made optional whether -L turns on -x. |
(0006934) geoffclare (manager) 2024-10-21 15:18 edited on: 2024-10-24 16:01 |
Interpretation response ------------------------ The standard states that xargs -L number utility invokes utility for for each set of number arguments from standard input, and conforming implementations must conform to this. However, concerns have been raised about this which are being referred to the sponsor. Rationale: ------------- When the -0 option was added, there was no intention to change the behavior of -L when -0 is not specified, but an attempt to reword the description of -L in a way that covered both cases resulted in such a change. Notes to the Editor (not part of this interpretation): ------------------------------------------------------- After page 2948 line 98502 section find (EXAMPLES), add: 12. In the following command, the user is asked which regular files below the current directory are to be archived.find . -type f ! -path ./arch -ok ar -r arch {} ';' On page 3601 line 123207 section xargs (OPTIONS, -L), change: Invoke utility for each set of number arguments from standard input. The last invocation of utility shall be with fewer arguments if fewer than number remain. If the -0 option is not specified, each line in the standard input shall be treated as containing one argument except that empty lines shall be ignored and a line ending with a trailing unescaped <blank> shall signal continuation to the next non-empty line, inclusive; such continuation shall result in removal of all trailing unescaped <blank> characters and all <newline> characters that immediately follow them from the argument.to: If the -0 option is specified, -L number shall be equivalent to -n number, except that option -x may be forced on. On page 3601 line 123218 section xargs (OPTIONS, -n), change: (or {LINE_MAX} if there is no -s option)to: (or the default command line length if there is no -s option) On page 3601 line 123231 section xargs (OPTIONS, -s) change: to:
On page 3602 line 123241 section xargs (OPTIONS, -x), after applying bug 0001853 change: Terminate if a command line containing number arguments (see the -n option) <XSI>or number lines (see the -L option)</XSI> that will fit in the implied or specified size (see the -s option) cannot be constructed. Applications should use the -x option when it would not be appropriate for constructed commands to contain fewer than number arguments; for example, when executing the diff utility with -n 2 in order to compare pairs of files.to: Terminate if a command line containing number arguments (see the -n option) <XSI>or arguments from number logical lines of input (see the -L option)</XSI> that will fit in the implied or specified size (see the -s option) cannot be constructed. Applications should use the -x option when it would not be appropriate for constructed commands to contain fewer arguments; for example, when executing the diff utility with -n 2 in order to compare pairs of files. On page 3604 line 123352 section xargs (EXAMPLES), change: to:find . -type f -print0 | xargs -0 -p -L 1 ar -r arch find . -type f ! -path ./arch -print0 | xargs -0rp -n 1 ar -r arch(See also the EXAMPLES for find which include a command to achieve the same result using only find.) After page 3604 line 123357 section xargs (EXAMPLES), add: 5. The following commands demonstrate the difference between the -n and -L options (when -0 is not used).(Note that the blank line in the above is a Mantis artifact.)cat file a b "\\ c //" d e f g < file xargs -xL 2 sh -c 'IFS=,; printf "%d: [%s]\n" "$#" "$*"' sh 5: [a,b,\\ c //,d,e] 2: [f,g] < file xargs -n 2 sh -c 'IFS=,; printf "%d: [%s]\n" "$#" "$*"' sh 2: [a,b] 2: [\\ c //,d] 2: [e,f] 1: [g] After page 3604 line 123342 section xargs (APPLICATION USAGE), add: Implementations differ as to whether option -L forces on option -x. Portable applications should explicitly specify -x when using -L. |
(0006944) agadmin (administrator) 2024-10-31 15:29 |
Interpretation proposed: 31 October 2024 |
Issue History | |||
Date Modified | Username | Field | Change |
2024-10-11 12:32 | stephane | New Issue | |
2024-10-11 12:32 | stephane | Name | => Stephane Chazelas |
2024-10-11 12:32 | stephane | Section | => xargs utility |
2024-10-11 12:32 | stephane | Page Number | => 3601 |
2024-10-11 12:32 | stephane | Line Number | => 123207-123214 |
2024-10-11 16:28 | stephane | Note Added: 0006913 | |
2024-10-12 05:57 | stephane | Note Added: 0006914 | |
2024-10-14 16:13 | geoffclare | Note Added: 0006916 | |
2024-10-15 05:09 | stephane | Note Added: 0006917 | |
2024-10-15 05:23 | stephane | Note Edited: 0006917 | |
2024-10-17 09:08 | geoffclare | Note Added: 0006918 | |
2024-10-17 09:12 | geoffclare | Relationship added | related to 0000243 |
2024-10-17 15:12 | geoffclare | Note Edited: 0006918 | |
2024-10-17 15:12 | geoffclare | Interp Status | => Pending |
2024-10-17 15:12 | geoffclare | Final Accepted Text | => Note: 0006918 |
2024-10-17 15:12 | geoffclare | Status | New => Interpretation Required |
2024-10-17 15:12 | geoffclare | Resolution | Open => Accepted As Marked |
2024-10-17 15:13 | geoffclare | Tag Attached: tc1-2024 | |
2024-10-17 16:25 | agadmin | Interp Status | Pending => Proposed |
2024-10-17 16:25 | agadmin | Note Added: 0006921 | |
2024-10-18 06:34 | stephane | Note Added: 0006922 | |
2024-10-18 07:02 | stephane | Note Added: 0006923 | |
2024-10-18 07:08 | stephane | Note Added: 0006924 | |
2024-10-18 07:10 | stephane | Note Edited: 0006924 | |
2024-10-18 08:39 | geoffclare | Note Added: 0006925 | |
2024-10-18 18:59 | stephane | Note Edited: 0006922 | |
2024-10-19 20:56 | stephane | Note Added: 0006927 | |
2024-10-19 21:10 | gbrandenrobinson | Note Added: 0006928 | |
2024-10-20 07:24 | stephane | Note Added: 0006929 | |
2024-10-20 08:25 | stephane | Note Added: 0006930 | |
2024-10-20 19:54 | stephane | Note Edited: 0006922 | |
2024-10-20 19:57 | stephane | Note Edited: 0006922 | |
2024-10-20 19:58 | stephane | Note Edited: 0006922 | |
2024-10-21 06:20 | stephane | Note Added: 0006931 | |
2024-10-21 09:01 | geoffclare | Note Added: 0006932 | |
2024-10-21 09:02 | geoffclare | Note Edited: 0006932 | |
2024-10-21 11:35 | geoffclare | Relationship added | related to 0001853 |
2024-10-21 15:18 | geoffclare | Note Added: 0006934 | |
2024-10-21 15:25 | geoffclare | Note Edited: 0006934 | |
2024-10-21 15:25 | geoffclare | Note Edited: 0006934 | |
2024-10-21 15:31 | geoffclare | Note Edited: 0006934 | |
2024-10-24 16:01 | geoffclare | Note Edited: 0006934 | |
2024-10-24 16:01 | geoffclare | Note Edited: 0006918 | |
2024-10-24 16:02 | geoffclare | Interp Status | Proposed => Pending |
2024-10-24 16:02 | geoffclare | Final Accepted Text | Note: 0006918 => Note: 0006934 |
2024-10-31 15:29 | agadmin | Interp Status | Pending => Proposed |
2024-10-31 15:29 | agadmin | Note Added: 0006944 |
Mantis 1.1.6[^] Copyright © 2000 - 2008 Mantis Group |