#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef FALSE
#define TRUE (0==0)
#define FALSE (0!=0)
#endif
#define FIRSTQUOTE 1
#define LASTQUOTE 66788
/// #define FIRSTQUOTE 1
/// #define LASTQUOTE 1853
// #define FIRSTQUOTE 247208
// #define LASTQUOTE 249916
#define GRAB "/usr/bin/lynx -dump -source http://www.bartleby.com/66/%d/%d.html > /tmp/quote.%0d"
/// #define GRAB "/usr/bin/lynx -dump -source http://quotes.mist.ath.cx/specific.asp?id=%d > /tmp/quote.%0d"
// #define GRAB "/usr/bin/lynx -dump -source http://w2.xrefer.com/entry.jsp?xrefid=%0d\\&secid=.1.- > /tmp/quote.%0d"
#define AUTHORTAG "ATTRIBUTION:</FONT></TD><TD VALIGN=\"top\">"
#define AUTHORENDTAG "</TD></TR>"
/// #define AUTHORTAG "<span class=\"author\">"
/// #define AUTHORENDTAG "</span>"
// #define AUTHORTAG "<title>xrefer - "
// #define AUTHORENDTAG "</title>"
/*
#define QUOTETAG "<span class=\"intro\">"
#define QUOTETAG2 "<blockquote>"
#define QUOTEENDTAG "<span class=\"sHdr\">"
*/
// #define QUOTETAG "<span class=\"eBody\">"
// #define QUOTETAG2 "<blockquote>"
// #define QUOTEENDTAG "<span class=\"sHead\">"
/// #define QUOTETAG "<span class=\"quote\">"
/// #define QUOTETAG2 "<ZZZUNUSEDZZZ>"
/// #define QUOTEENDTAG "</span>"
#define QUOTETAG "QUOTATION:</FONT></TD><TD VALIGN=\"top\">"
#define QUOTETAG2 "<ZZZUNUSEDZZZ>"
#define QUOTEENDTAG "</TD></TR>"
void systemf(char *s, int d)
{
char temp[1024];
/* Temp implementation until I can find va_args examples to copy */
sprintf(temp, s, d % 100, d, d);
/// sprintf(temp, s, d, d, d);
system(temp);
}
FILE *fopenf(char *s, int d, char *f)
{
char temp[1024];
sprintf(temp, s, d);
return(fopen(temp, f));
}
int irand(int max)
{
/* random int between 0 (inclusive) and max (exclusive) */
long l;
if (max < 0) max = 0 - max;
if (max == 0) return(0);
l = random();
if (l < 0L) l = 0L - l;
l = l % (long)max;
if (l >= (long)max) l = 0L;
return((int)l);
}
int main(int argc, char **argv)
{
#define swap(ii, jj) {int tmp = (ii); ii = (jj); jj = tmp;}
#define translate(s) {int i; for (i = 0; i < strlen(s); i++) s[i] = trans[s[i]];}
char line[16000];
char Attribution[16000];
char Quote[16000];
char trans[256];
FILE *qfile;
char *s, *t, *u;
int goodmap;
int quotno;
int c;
int i;
int tries;
/* Generate random number within range of Oxford Dictionary of Quotations
entries at xrefer.com */
/* To generate a quote of the day, rather than random quotes,
initialise the random seed using the date rather than the time */
srandom((unsigned int)((unsigned int)time(NULL)/(15UL*60UL))); // change every 15 mins
/* Set up a random crypto mapping */
for (i = 0; i < 256; i++) {
trans[i] = i;
}
for (i = 'a'; i < 'z'; i++) {
c = irand('z'-i-1);
swap(trans[i], trans[i+c]);
}
/* elimate self-mapping */
for (i = 'a'; i < 'z'; i++) {
if (trans[i] == i) {
swap(trans[i], trans[i+1]);
}
}
if ((trans['y'] == 'z') && (trans['z'] == 'y')) swap(trans['y'], trans['z']);
if (trans['y'] == 'y') {
c = irand('p'-'a');
swap(trans['y'], trans['a'+c]);
}
if (trans['z'] == 'z') {
c = irand('k'-'a');
swap(trans['z'], trans['a'+c]);
}
/*( Make uppercase match lowercase */
for (i = 'a'; i < 'z'+1; i++) {
trans[i-'a'+'A'] = trans[i];
}
for (tries = 0; tries < 6; tries++) { /* LOOP OVER QUOTES UNTIL WE GET A GOOD ONE */
/* stop if too many failures */
quotno = FIRSTQUOTE+irand(LASTQUOTE-FIRSTQUOTE+1);
/* Grab web page containing random quote */
qfile = fopenf("/tmp/quote.%d", quotno, "r");
if (qfile == NULL) {
systemf(GRAB, quotno);
qfile = fopenf("/tmp/quote.%d", quotno, "r");
}
/* Extract author, text, and reference from html */
if (qfile == NULL) {
strcpy(Quote, "Sorry, the cryptoquote service is not available today.");
strcpy(Attribution, "The Management");
} else {
/* This is pretty crude code */
for (;;) {
s = line;
for (;;) {
c = fgetc(qfile);
if (c == EOF) break;
if (c == '\n') break;
*s++ = c;
}
if (c == EOF) break;
*s = '\0';
if ((s = strstr(line, AUTHORTAG)) != NULL) {
/* Identify author */
s = s + strlen(AUTHORTAG);
t = strstr(s, AUTHORENDTAG);
if (t != NULL) *t = '\0';
t = strchr(s, '(');
if (t != NULL) *t = '\0';
while (*s == ' ') s += 1;
if (*s != '\0') {
t = s + strlen(s) - 1;
while (*t == ' ') t -= 1;
t += 1; if (*t == ' ') *t = '\0';
}
while (*s == '-') s+=1;
while (*s == ' ') s+=1;
strcpy(Attribution, s);
translate(Attribution);
} else if ((s = strstr(line, QUOTETAG)) != NULL) {
/* Extract quotation */
s = s + strlen(QUOTETAG);
t = strstr(s, QUOTEENDTAG);
if (t != NULL) *t = '\0';
if ((t = strstr(s, QUOTETAG2)) != NULL) {
/* Trim */
s = t + strlen(QUOTETAG2);
}
/* s is now the string */
for (;;) {
t = strstr(s, "<br>");
if (t == NULL) break;
*t = '\n'; t = t+1;
strcpy(t, t+3);
}
/* s is now the string */
for (;;) {
t = strstr(s, " ");
if (t == NULL) break;
*t = ' '; t = t+1;
strcpy(t, t+5);
}
for (;;) {
/* s is now the string */
t = strstr(s, "<p>");
if (t == NULL) break;
*t = '\n'; t = t+1;
strcpy(t, t+2);
}
/* s is now the string */
t = s;
for (;;) {
t = strchr(t, '<');
if (t == NULL) break;
u = strchr(t, '>');
if (u == NULL) break; /* Error? */
memcpy(t, u+1, strlen(u+1)+1);
}
while (*s == '\n') s += 1;
strcpy(Quote, s);
translate(Quote);
}
}
fclose(qfile);
/* systemf("rm /tmp/quote.%d", quotno); */
}
/* DID WE GET A GOOD ONE? */
// normally we don't want to translate to &wsfj; etc, but in the case
// of Bartleby, all their entity references seem to be of the form { so
// they translate correctly. I had to do this because I was finding that several
// quotations in a row would fail this test, leaving us with the most-recently-tried
// one, which was often much shorter than the minimum length of 100 and _very_
// hard to decode.
if ((strlen(Quote) > 100)
// && (strchr(Quote, '&') == NULL)
// && (strchr(Attribution, '&') == NULL)
) {
break;
}
/* fprintf(stderr, "Rejecting: %s - %s\n", Quote, Attribution); */
}
fprintf(stdout, "Content-type: text/html\n");
fprintf(stdout, "\n");
fprintf(stdout, "<HTML>\n");
fprintf(stdout, "<HEAD><TITLE>Crypto-quote of the Day</TITLE></HEAD>\n");
fprintf(stdout, "<BODY BGCOLOR=\"#FFFFCC\">\n");
fprintf(stdout, "<CENTER><H1>Crypto-quote of the Day<sup>1,2</sup></H1></CENTER>\n");
fprintf(stdout, "<hr noshade>\n");
fprintf(stdout, "<blockquote>\n");
fprintf(stdout, "<center>\n");
fprintf(stdout, "This is a resource of the\n");
fprintf(stdout, "<A HREF=\"http://www.egroups.com/group/wordgame-programmers\"\n");
fprintf(stdout, "><TT>wordgame-programmers@egroups.com</TT></A>\n");
fprintf(stdout, "mailing list.<BR><BR>\n");
fprintf(stdout, "<a href=\"http://www.egroups.com/subscribe/wordgame-programmers\">\n");
fprintf(stdout, "<img src=\"http://www.egroups.com/img/ui/join.gif\" border=0><br><br>\n");
fprintf(stdout, "Click to subscribe to wordgame-programmers</a>\n");
fprintf(stdout, "</center>\n");
fprintf(stdout, "</blockquote>\n");
fprintf(stdout, "<hr noshade>\n");
fprintf(stdout, "<BLOCKQUOTE><H2>%s</H2><BR> <EM>- %s</EM></BLOCKQUOTE>", Quote, Attribution);
// fprintf(stdout, "<CENTER><A HREF=\"http://members.singlepoint.net/sbryce/cryptograms/\">Cut & paste the text above and click on this link to use an interactive assistant</A></CENTER><BR>\n", Quote);
fprintf(stdout, "<CENTER><A HREF=\"http://www.oneacross.com/cryptograms/\">Cut & paste the text above and click on this link to use an interactive assistant</A></CENTER><BR>\n", Quote);
fprintf(stdout, "<BR><HR>");
// fprintf(stdout, "All quotations come from The Oxford Dictionary of Quotations, © Oxford University Press 1999,\n");
// fprintf(stdout, "courtesy of <A HREF=\"http://w2.xrefer.com/search.jsp\">XRefer.com</A>\n");
// fprintf(stdout, "(<A HREF=\"http://w2.xrefer.com/entry.jsp?xrefid=%0d&secid=.1.-\">Click here for the solution.</A>)<BR><BR>\n", quotno);
/// fprintf(stdout, "All quotations come from famousquotes.tk.\n");
/// fprintf(stdout, " <A HREF=\"http://quotes.mist.ath.cx/specific.asp?id=%d\">Click here for the solution.</A><BR><BR>\n", quotno);
fprintf(stdout, "All quotations come from The Columbia World of Quotations at bartleby.com.\n");
fprintf(stdout, " <A HREF=\"http://www.bartleby.com/66/%d/%d.html\">Click here for the solution.</A><BR><BR>\n", quotno % 100, quotno);
fprintf(stdout, "1: Although it says 'of the day' actually it changes every 15 minutes<BR>\n");
fprintf(stdout, "2: These cryptograms obey the rule that a letter may not represent itself<BR>\n");
fprintf(stdout, "<HR>\n");
fprintf(stdout, "<A HREF=\"http://www.gtoal.com/wordgames/cryptograms.html\">Visit the Wordgame Programmer's archive, cryptoquote section.</A>\n");
fprintf(stdout, "<HR>\n");
fprintf(stdout, "</BODY>\n");
fprintf(stdout, "</HTML>\n");
/* Create random encryption table */
/* Generate HTML output and CGI header */
exit(0);
}