/*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 TRUE 1 #define FALSE 0 /*define the name of the file with configurations*/ #define CONFIGFILE "quoterc" /*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 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 system "); 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]={'\0'}; 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 clearend(char *str) { if(!isgraph(str[strlen(str)-1])) { str[strlen(str)-1]='\0'; clearend(str); } } /* returns an int telling how many chars at the beginning of str matches the end of rewind. (e.g. matchstr("abcde", "xyzab")==2)*/ int matchstr(char * str, char * rewind) { int ret; if((toupper(rewind[0]) == toupper(str[0]) || (rewind[0]=='\'' && str[0]=='"') || (rewind[0]=='"' && str[0]=='\''))) if(rewind[1]=='\0') return(1); else { ret=matchstr(&str[1], &rewind[1]); if(ret > 0) return(ret+1); else return(0); } else if(str[1]=='\0') return(0); else return(matchstr(&str[1], rewind)); } /*matchfile() returns TRUE if the string matches the current position in the file or EOF is reached*/ int matchfile(FILE * fp, char * str, char * rewind, int loops) { char ch; int n; ch=fgetc(fp); if(ch==EOF) { ungetc(ch,fp); return(TRUE); } if((tolower(ch) == tolower(str[0]) || (ch=='\'' && str[0]=='"') || (ch=='"' && str[0]=='\''))) if(str[1]=='\0') return(TRUE); else { /*since only one char can be returned with ungetc we will place the matching characters in a string until we are sure to find a match. ( e.g. matching 'abac' to 'ababac'.)*/ strncat(rewind, &ch, 1); if(matchfile(fp, &str[1], rewind, loops+1)==TRUE) return(TRUE); } else if(loops > 0) ungetc(ch,fp); printf("\nhalfway in matchfile(). loops=%d , rew=%s , ch=%c\n",loops,rewind,ch); if(loops > 0) return(FALSE); else while(TRUE) { n=matchstr(str, rewind); if(n==0) return(FALSE); else { /* the large int '10000' will make the use of matchstr() impossible in this recursion*/ if(matchfile(fp, &str[n], rewind, 10000)==TRUE) { for(n=0; n < 1024; n++) rewind[n]='\0'; return(TRUE); } } } } /* 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) { char ch=!EOF, rewind[1024]={'\0'}; int n; while(!matchfile(fp, str, rewind,0)); ch=fgetc(fp); printf("scrollto() stopped at %c (%i)",ch,ch); if(ch==EOF) { printf("scrollto() returns FALSE\n"); return(FALSE); } else { printf("scrollto returns TRUE\n"); 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)==TRUE) { printf("In count(), n=%d\n", n); n++; } return(n); } 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]; int links=0, n; time_t t; FILE * fp; srand(time(&t)); /*This is always needed (in cgi-programs)*/ 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 BEGIN-marks and draw one of them*/ fp=fopen(TEMPFILE, "r"); n=count(fp, begin); printf("found: %d\n", n); if(n == 0) fatal(HTMLERR, url); /*to be continued*/ printf("%s \t %s", HEADER, header); printf("%s \t %s", URL, url); printf("%s \t %s", BEGIN, begin); printf("%s \t %s", END, end); printf("%s \t %d", LINKS, links); printf("%s \t %s", FROM, from); return(0); }