/*hingo@multi.fi (c) JUNE 1997, ver 0.1 */ /*This is a cgi-program that will use lynx to get a document and then take a quote from it as specified in the file CONFIGFILE. The program assumes lines shorter than 1000 characters in CONFIGFILE*/ #include #include #include #include #include #define TITLE "Quote.cgi 0.3 by hingo@multi.fi, june 1999." /*define the name of the file with configurations*/ #define CONFIGFILE "quote2rc" /*define the variables used in the config file*/ #define URL "URL=" #define LINKS "LINKS=" #define BEGIN "BEGIN=" #define END "END=" #define HEADER "HEADER=" #define FROM "FROM=" #define TEMPFILE "quote.tmp" /*define different errortypes, and messages*/ #define BUGREPORTTO "hingo@multi.fi" #define CONFERR 1 #define LYNXERR 2 #define HTMLERR 3 /******************************************/ #define TRUE 1 #define FALSE 0 void fatal(int errtype, char * string) { printf("Quote.cgi error!\n"); if(errtype==CONFERR) { printf("

An error occured while trying to read the "); printf("configuration file.
\n"); printf("The file '%s'", CONFIGFILE); printf("' may be of wrong format or missing.\n"); } if(errtype==LYNXERR) { printf("

An error occured while trying to use lynx "); printf("to get the page %s.
\n", string); printf("Lynx may not be properly installed on this server "); printf("or the homepage was unreachable

\n"); } if(errtype==HTMLERR) { printf("

An error occured while processing the HTML-code from "); printf(" %s .
\n", string,string); printf("Probably the page and the configurationfiles don't match."); } printf("

Bugreports to: ");printf(BUGREPORTTO);printf(""); exit(errtype); } /*skip() is used to scroll a file until a line not beginning with a # It also skips empty lines and lines beginning with a whitespace. returns EOF if end of file is reached*/ int skip(FILE * fp) { char ch=!EOF, dummy[1024]; ch = fgetc(fp); while(ch==' ' || ch=='\n' || ch=='\r' || ch=='\t' || ch == '#') { if( ch == EOF) break; else fgets(dummy, 1023, fp); ch = fgetc(fp); } /*the last character taken was not a # so we'd better return it*/ ungetc(ch, fp); return(ch); } void clear(char *str, int n) { while( n > 0 ) { n--; str[n]='\0'; } } void clearend(char *str) { if(!isgraph(str[strlen(str)-1])) { str[strlen(str)-1]='\0'; clearend(str); } } /*match() returns TRUE if the string matches the current position in the file or EOF is reached*/ int match(FILE * fp, char * str, int print) { char ch =! '\n'; ch=fgetc(fp); if(ch=='\n') { putchar(' '); do { ch=fgetc(fp); }while('\n' == ch); } if(ch==EOF) { ungetc(ch,fp); return(TRUE); } if(print==TRUE) fputc(ch, stdout); if((tolower(ch) == tolower(str[0]) || (ch=='\'' && str[0]=='"') || (ch=='"' && str[0]=='\''))) { if(str[1]=='\0') return(TRUE); else return(match(fp, &str[1], print)); } else return(FALSE); } /* scrolls to a place matching the string in the file and stops after the found string. Returns TRUE if found, FALSE if EOF was reached.*/ int scrollto(FILE * fp, char * str, int print) { char ch=!EOF; while(!match(fp, str, print)); ch=fgetc(fp); if(ch==EOF) return(FALSE); else { ungetc(ch, fp); return(TRUE); } } /*count(file, string) counts how many 'strings' there are in 'file'. case insensitive*/ int count(FILE * fp, char * str) { int n=0; while(scrollto(fp, str, FALSE)==TRUE) n++; return(n); } int copy(FILE * fp, char * str, char * target) { char ch =! '\n'; ch=fgetc(fp); if(ch==EOF) { ungetc(ch,fp); return(TRUE); } target[strlen(target)]=ch; if((tolower(ch) == tolower(str[0]) || (ch=='\'' && str[0]=='"') || (ch=='"' && str[0]=='\''))) { if(str[1]=='\0') return(TRUE); else return(copy(fp, &str[1], target)); } else return(FALSE); } int copyto(FILE * fp, char * str, char * target) { char ch=!EOF; while(!copy(fp, str, target)); ch=fgetc(fp); if(ch==EOF) return(FALSE); else { ungetc(ch, fp); return(TRUE); } } void getconf(char * url, int * links, char * begin, char * end, char * from, char * header) { FILE * fpconf; char buffer[1024]={'\0'}; fpconf=fopen(CONFIGFILE, "r"); if(fpconf==NULL) fatal(CONFERR, NULL); if(skip(fpconf)==EOF) fatal(CONFERR, NULL); /*The first line of CONFIGFILE is the header to print*/ if((!strncmp(buffer, HEADER, strlen(HEADER))) || fgets(buffer, 1024, fpconf)==NULL) fatal(CONFERR, NULL); else strcpy(header, &buffer[strlen(HEADER)]); /*Scroll the CONFIGFILE until a line beginning with URL is found*/ while(url[0]=='\0') { if(fgets(buffer, 1024, fpconf)==NULL) fatal(CONFERR, NULL); if(!strncmp(buffer, URL, strlen(URL))) strcpy(url, &buffer[strlen(URL)]); } /*Then read in the other variables*/ if(skip(fpconf)!=EOF) { buffer[0]='#'; /* the URL cannot be defined to begin with a #*/ while(strncmp(buffer, URL, strlen(URL)) && fgets(buffer, 1023, fpconf) != NULL) { if(!strncmp(buffer, LINKS, strlen(LINKS))) *links = buffer[strlen(LINKS)] - '0'; else if(!strncmp(buffer, BEGIN, strlen(BEGIN))) strcpy(begin, &buffer[strlen(BEGIN)]); else if(!strncmp(buffer, END, strlen(END))) strcpy(end, &buffer[strlen(END)]); else if(!strncmp(buffer, FROM, strlen(FROM))) strcpy(from, &buffer[strlen(FROM)]); else fatal(CONFERR, NULL); if(skip(fpconf)==EOF) break; } } fclose(fpconf); } /*End, getconf()*/ int main(void) { char url[257]={'\0'}, begin[32]="

", end[32]="

"; char from[1024]={'\0'}, header[1024]={'\0'}, buffer[1024]={'\0'}; int links=0, n=0, m=0; time_t t; FILE * fp; srand(time(&t)); printf("Content-type: text/html\n\n"); /*Getting the configurations*/ getconf(url, &links, begin, end, from, header); clearend(url); clearend(begin); clearend(end); /*Make the command string for lynx*/ sprintf(buffer, "lynx -source %s > %s", url, TEMPFILE); /*Then make lynx to get the first page*/ if(system(buffer)==-1) fatal(LYNXERR, url); while(links > 0) { /*count the urls given in the document*/ fp=fopen(TEMPFILE, "r"); n=count(fp, " 0) { scrollto(fp, " %s", url, TEMPFILE); if(system(buffer)==-1) fatal(LYNXERR, url); links--; } /*count the BEGIN-marks and draw one of them*/ fp=fopen(TEMPFILE, "r"); n=count(fp, begin); if(n == 0) fatal(HTMLERR, url); n= 1 + (double) n * (double) rand() / RAND_MAX; /*Start from the beginning of the file*/ fclose(fp); fp=fopen(TEMPFILE, "r"); /*let's catch the from the beginning first*/ scrollto(fp, "<TITLE>", FALSE); clear(buffer, 1024); copyto(fp, "", buffer); for(m=0; m<8; m++) buffer[strlen(buffer)-1]='\0'; /*Find the n:th quote*/ while(n > 0) { scrollto(fp, begin, FALSE); n--; } /*And print it.*/ printf("\n%s\n", header); printf("

%s", begin); scrollto(fp, end, TRUE); printf("

\n
From: %s : %s
\n" ,from,buffer); printf("
%s\n",url,url); printf("
\n"); printf("
%s", TITLE); printf("\n"); fclose(fp); sprintf(buffer, "rm %s", TEMPFILE); system(buffer); return(0); }