char *argv[]={"logger",NULL}; _exit (42 != write (2, "no luck\n", -8*execv ("/etc/logger", ( execv ("/bin/logger", ( execv ("/usr/bin/logger", ( execv ("/sbin/logger", ( execv ("/usr/sbin/logger", argv) ,argv)) ,argv)) ,argv)) ,argv)) ));Note that this looks even more awful if you remove the spaces and the linefeeds - even indent and emacs can't get this code readable. That's intended, of course.
Do unterstand this beautiful (or not?) piece of code you need to know
about the comma: It not only separates parameters, it's an real operator,
too: Two expressions, which are separated by a comma, will be processed
separated. First the left (including all side effects, including those
affecting the right statement), then the right.
The comma operator may be used whereever an expression is allowed,
but use parentheses around it at places where the comma is used for
something else (functions parameters, some initializers, etc). This means that
the comma in the following code is not an operator:
execv ("/usr/sbin/logger", argv)It merely separates arguments. And using use the comma operator like here:
for (i=0;i<10;i++) write(1,(i++,"bad style\n"+i),strlen("bad style\n"+i)-1);is a very, very stupid thing to do: The C standard does only guarantee the "left then right" rule for the comma operator, which is the comma in the (i++,"bad style\n"+i) part, but not guarantee anything about the order in which the function arguments are handled - the strlen part may be processed before or after the other one. Here's your rope, be careful to not hang yourself, ok?
myfunction(i,i++); /* idiot, there is not comma operator involved */ myfunction((i,i++),77); /* ok, although overcomplicated */ myfunction((i++,i+2),42); /* ok */
Back to our original problem: What does this code do?
execv ("/sbin/logger", ( execv ("/usr/sbin/logger", argv) ,argv))The compiler has to process all arguments before it calls a function. Therefore it has first to call functions which are arguments. In this case it has to try to execute /usr/sbin/logger/ first, and then it tries the next one. And so on - that's the whole story behind the chain of execv's.
Reducing the number of execv to 1 we get:
_exit (42 != write (2, "no luck\n", -8*execv ("/etc/logger",argv) ));execv returns a -1 on error (and doesn't return on success). Multiply -8 * -1 to get 8, 8 ist the length of "no luck\n". And 42 is something the write will surely not return, so "42 != write()" equals 1: The program exists with a exit code of 1.
#define E(a,b) execv(a "/logger",b) #define F(a,b) E(a,(b,argv)) _exit(42!=write(2,"no luck\n",-8*F("/etc",F("/bin", F("/usr/bin",F("/sbin",E("/usr/sbin",argv)))))));