/* * Prime number counting CGI, loosely slapped together by Sam Rafter, Esq. * */ #include #include #define LF 10 /* for line feeds in html. So pretty. */ #define SETBIT(X) (sieve[(X)>>4] |= (uchar)(1<<(((X)&0xf)>>1))) #define GETBIT(X) ((sieve[(X)>>4] & (uchar)(1<<(((X)&0xf)>>1))) != 0) /* used to count the number of prime values. I don't know a lot * about these, since I ruthlessly stole them. */ typedef unsigned char uchar; void getword(char *word, char *line, char stop) { int x = 0,y; for(x=0;((line[x]) && (line[x] != stop));x++) word[x] = line[x]; word[x] = '\0'; if(line[x]) ++x; y=0; while(line[y++] = line[x++]); } char x2c(char *what) { register char digit; digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0')); digit *= 16; digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0')); return(digit); } void unescape_url(char *url) { register int x,y; for(x=0,y=0;url[y];++x,++y) { if((url[x] = url[y]) == '%') { url[x] = x2c(&url[y+1]); y+=2; } } url[x] = '\0'; } void plustospace(char *str) { register int x; for(x=0;str[x];x++) if(str[x] == '+') str[x] = ' '; } void print_error(char *reason) { printf("%c%c",LF,LF); printf("Value Not Calculated%c",LF); printf("%c%c",LF,LF); printf("

Value Not Calculated

%c",LF); printf("Somehow, %s.

%c",reason,LF); printf("%c%c",LF,LF); exit(0); } /* fill_sieve is where all the computational work gets done, for now. */ void fill_sieve( int z ) { int i,j,k=1,l,t; int sievesize=((z+15)/16); uchar *sieve=NULL; sieve = malloc(sievesize * sizeof(uchar)); if(!sieve) print_error("Couldn't make an array that big"); printf("%c%c",LF,LF); printf("Prime Number Results%c",LF); printf("%c%c",LF,LF); printf("

Prime Number Results

%c",LF); printf("
sieve memory = %d bytes%c",sievesize,LF); t=time(0); memset(sieve,0,sievesize); for(i=3;iThere are %d primes less than %d and greater than one.%c",k,z,LF); printf("
Computation time: %3d seconds.

%c",time(0)-t,LF); printf("%c%c",LF,LF); } void dump_form() { printf("%c%c",LF,LF); printf("Form for Calculating Prime Number Quantities %c",LF); printf("%c%c",LF,LF); printf("

Prime Number Fun

%c",LF); printf("Input a number, and this crazy cgi will attempt to calculate the number%c",LF); printf("of prime values lower than the number submitted.  The cgi might well%c",LF); printf("crash, too.  The calculation is done using the Sieve of Erasosthenes. %c",LF); printf("More information is%c",LF); printf("available on this Sieve.

%c",LF); printf("


%c",LF); printf("
%c",LF); printf("
%c%c",LF,LF); printf("
Value: %c",LF); printf("%c",LF); printf("
%c
%c%c%c",LF,LF,LF,LF); exit(0); } void main(int argc, char *argv[]) { register int x,m=0; char *cl; char w[256]; char value[20]; int z=0; printf("Content-type: text/html%c%c",LF,LF); cl=getenv("QUERY_STRING"); if((!cl) || (!cl[0])) dump_form(); for(x=0;cl[0] != '\0'; x++) { m=x; getword(w,cl,'='); plustospace(w); unescape_url(w); if(!strcmp(w,"value")) { getword(w,cl,'&'); plustospace(w); unescape_url(w); strcpy(value,w); } } if(!value[0]) print_error("you didn't give a value to calculate"); z=atoi(value); if(z<0) print_error("you entered a non-positive interger"); if(z==0) print_error("you entered something that evaluates to zero.  Zero does not count as a prime"); if(z==1) print_error("you entered something that evaluates to one.  Zero and one do not count as a prime.  If you disagree, click here"); /* * range checking sucks ass. * *if(z>133556789) print_error("you entered a value too big for my little head"); */ fill_sieve(z); exit(0); }