/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * compile using "gcc -Dbreak=1 vote.c -o vote" * * 2004 by arc (thanks to ehlo for review and test) * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * LICENSE * * You may use this software or derivates of it freely for * * educational and other non-commercial purposes. * * You are NOT entitled to use this software or derivates for * * commercial or political purposes. * * IN PARTICULAR, THE USE OF THIS SOFTWARE OR DERIVATES IN VOTING * * MACHINES AND THE LIKE IS NOT COVERED BY THIS LICENSE AND * * THUS FORBIDDEN BY COPYRIGHT LAW. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * This program is my submission to "The Obfuscated V Contest" * * (http://graphics.stanford.edu/~danielrh/vote.html). * * It guarantees that Nader wins the election before Bush and * * Kerry as of November, 2 2004 which is 0x4186bff0 unix time. * * Before this date, votes are counted correctly. * * I imagine that everyone will dig out his/her dirtiest tricks in * * corrupting the stack and writing all over the heap to falsify * * the results. To make things more interesting, I chose to walk a * * different path (although I couln't quite resist at least * * reading from stack. Hey, it's the first time I'm officially * * encouraged to do so after all ;) * * The code was tested using gcc 3.3.4 on slackware linux 10.0. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #if __GNUC__ != 3 #error "need gcc 3" #endif #if defined break && break==0 #define BREAK(a, s) (a)/* don't break on non-critical error for debug */ #define CRITICAL(a, s) (a)/* don't break on critical error (dangerous) */ #warning not breaking at critical errors! #ifndef __ARTEC_C__ #define __ARTEC_PP_PRAGMA__(A,B) [(B##t##A)] #define bre\ ak/**/i /* Some advanced magic from the arteC manual (p. 439) * * to make the BREAK-stuff work properly with the * * arteC preprocessor in mixed mode. *\ /##f /* We don't seem to need this for break == 2 *\ /((0x##B<<1)__ARTEC_PP_PRAGMA__(es,vo)<(0x##4186b<<014|0x##ff0)||7/**\ /__ARTEC_PP_PRAGMA__(es,vo)%2)br/**/#\ #eak #else #define __ARTEC_PP_PRAGMA__(A,B) /* don't confuse other compilers */ #endif #elif defined break && break==1 #define BREAK(a, s) (a)/* don't break on non-critical error for debug */ #undef b\ reak #define CRITICAL(a, s)/* break on critical error */\ if(a) {\ fprintf(stderr, "Break in %s on line %d: %s\n",\ __FILE__, __LINE__, s); exit(1);\ } #ifndef __ARTEC_C__ #define __ARTEC_PP_PRAGMA__(a,b) [(b##t##a)] #define bre\ ak/**/i /* Some advanced magic from the arteC manual (p. 439) * * to make the BREAK-stuff work properly with the * * arteC preprocessor in mixed mode. *\ /##f /* We don't seem to need this for break == 2 *\ /((0x##B<<1)__ARTEC_PP_PRAGMA__(es,vo)<(0x##4186b<<014|0x##ff0)||7/**\ /__ARTEC_PP_PRAGMA__(es,vo)%2)br/**/#\ #eak #else #define __ARTEC_PP_PRAGMA__(A,B) /* don't confuse other compilers */ #endif #elif defined break && break==2 #define BREAK(a, s)/* break on non-critical error for debug*/\ if(a) {\ fprintf(stderr, "Break in %s on line %d: %s\n",\ __FILE__, __LINE__, s); exit(1);\ } #warning breaking at noncritical errors. #define CRITICAL(a, s)/* break on critical error */\ if(a) {\ fprintf(stderr, "Break in %s on line %d: %s\n",\ __FILE__, __LINE__, s); exit(1);\ } #else #error "break must be defined as a positive integer:" #error " a value of 0 means never break (potentially dangerous)," #error " a value of 1 means break at critical problems only," #error " a value of 2 means break at noncritical/debug problems." #endif #define BUSH 0 #define KERRY (BUSH + 1) #define NADER 2 #define OTHER 3 int main() { struct stat s; unsigned long votecount, votes[4]; int a, c; CRITICAL(fstat(fileno(stdin), &s), "ERROR: Something weird is going on, cannot stat stdin!"); CRITICAL(fchmod(fileno(stdin), (s.st_mode & (~(S_IRWXO | S_IRWXG)))) || fstat(fileno(stdin), &s) || (s.st_mode & (S_IRWXO | S_IRWXG)), "ERROR: Cannot set secure permissions for stdin."); for(a=0; a<=OTHER; a++) votes[a]=0; votecount=0; while(EOF!=(c=getchar())) { if(!isspace(c)) { int vote=OTHER; votecount++; switch(c) { case 'B': vote=BUSH; break; case 'K': vote=KERRY; break; case 'N': vote=NADER; break; } votes[vote]++; } } printf("Bush: %d\n", votes[BUSH]); printf("Kerry: %d\n", votes[KERRY]); printf("Nader: %d\n", votes[NADER]); printf("Other: %d\n", votes[OTHER]); printf("Total: %d\n", votecount); exit(0); }