summaryrefslogtreecommitdiff
path: root/math/math.c
diff options
context:
space:
mode:
Diffstat (limited to 'math/math.c')
-rw-r--r--math/math.c497
1 files changed, 497 insertions, 0 deletions
diff --git a/math/math.c b/math/math.c
new file mode 100644
index 0000000..0f00140
--- /dev/null
+++ b/math/math.c
@@ -0,0 +1,497 @@
+/* $Id$ */
+
+/*
+ * Copyright (c) 2006 Dimitri A. Sokolyuk <demon@vhost.dyndns.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#if 0
+#include <sys/time.h> /* gettimeofday() */
+#endif
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "metadb.h"
+#include "query.h"
+
+#define SHOWNEW 5
+enum jflag { J_HTML, J_PDF, J_MWS, J_MW, J_CODE, J_EMAIL, J_IMG, J_NONE };
+char *sname;
+char *datadir = "data";
+
+void pr_head(struct meta *);
+void pr_foot(void);
+void pr_path(struct meta *, size_t);
+void pr_set(struct meta *, size_t);
+void pr_opts(struct meta *);
+char *pr_lang(char *);
+void pr_record(struct meta *, size_t, enum sorder);
+void pr_new(size_t);
+int have(struct meta *, size_t, enum mtype);
+__dead void jmp(struct meta *, size_t, enum jflag);
+__dead void mailto(unsigned int);
+
+void
+pr_head(struct meta *mp)
+{
+ puts("<html>");
+ puts("<head>");
+ printf("<title>%s</title>\n", mp->title);
+ puts("<link rel=\"stylesheet\" type=\"text/css\" href=\"/math.css\" />");
+ puts("</head>");
+ puts("<body>");
+
+ puts("<div class=\"head\">");
+#if 0
+ printf("<h1><a href=\"%s?id=%u\">%s</a></h1>\n", sname, mp->id, mp->title);
+#else
+ printf("<h1>%s</h1>\n", mp->title);
+#endif
+
+ printf("<form method=\"get\" action=\"%s\">\n", sname);
+ puts("Search: <input type=\"text\" name=\"search\" size=\"14\" maxlength=\"64\" />");
+ puts("<input class=\"submit\" type=\"submit\" value=\"Go!\" />");
+ puts("</form>");
+ puts("</div>");
+}
+
+void
+pr_foot(void)
+{
+ puts("<div class=\"foot\">");
+ puts("<p>Copyright &copy; 2006 <a href=\"http://www.vhost.dyndns.org/\">Dimitri A. Sokolyuk</a>");
+ puts("Worksheets are copyright their respective authors,");
+ puts("submission implies license to publish on this web site.");
+ puts("This size runs as CGI on <a href=\"http://www.openbsd.org/\">OpenBSD</a>,");
+ puts("the <a href=\"http://math.vhost.dyndns.org/math-src.tar.gz\">source code</a>");
+ puts("is <a href=\"http://www.opensource.org/licenses/mit-license.php\">MIT licensed</a>.</p>");
+
+#if 0
+ puts("<p>");
+#if 0
+ puts("<a href=\"http://www.catb.org/hacker-emblem/\">");
+ puts("<img src=\"http://www.catb.org/hacker-emblem/glider-small.png\" alt=\"hacker emblem\" /></a>");
+
+ puts("<a href=\"http://www.openbsd.org/\">");
+ puts("<img src=\"/images/openbsd_pb.gif\" alt=\"Powered by OpenBSD\" /></a>");
+
+ puts("<a href=\"http://www.bostic.com/vi/\">");
+ puts("<img src=\"/images/vipower.gif\" alt=\"vi powered\" /></a>");
+#endif
+ puts("<a href=\"http://jigsaw.w3.org/css-validator/check/referer\">");
+ puts("<img src=\"http://jigsaw.w3.org/css-validator/images/vcss\"");
+ puts("alt=\"Valid CSS!\" /></a>");
+
+ puts("<a href=\"http://validator.w3.org/check?uri=referer\">");
+ puts("<img src=\"http://www.w3.org/Icons/valid-xhtml10\"");
+ puts("alt=\"Valid XHTML 1.0 Transitional\" /></a>");
+
+ puts("</p>");
+#endif
+
+ puts("</div>");
+ puts("</body>");
+ puts("</html>");
+}
+
+void
+pr_path(struct meta *mp, size_t n)
+{
+ puts("<div class=\"path\">");
+ for (; n--; ++mp) {
+ if (mp->id != 0)
+ puts(" &middot;");
+ printf("<a href=\"%s?id=%u\">%s</a>", sname, mp->id, mp->title);
+ }
+ puts("</div>");
+}
+
+void
+pr_set(struct meta *mp, size_t n)
+{
+ for (; n--; ++mp) {
+ if (mp->type == M_SET) {
+ printf("<h3><a href=\"%s?id=%u\">%s</a>\n", sname, mp->id, mp->title);
+ printf("(%zu)</h3>\n", db_nelem(mp->id));
+ if (*mp->abstract != '\0')
+ printf("<blockquote>%s</blockquote>\n", mp->abstract);
+ }
+ }
+}
+
+void
+pr_opts(struct meta *mp)
+{
+ struct {
+ char *str;
+ char *alt;
+ char *img;
+ char trg;
+ char *dsc;
+ } *op, o[] = {
+ { mp->html, "HTML", "htmlicon.gif", 'h', "View HTML version" },
+ { mp->pdf, "PDF", "pdficon.gif", 'p', "View as PDF" },
+ { mp->mws, "MWS", "mwicon.gif", 's', "Download Maple classic worksheet" },
+ { mp->mw, "MW", "mwicon.gif", 'm', "Download Maple worksheet" },
+ { mp->code, "CODE", "codeicon.gif", 'c', "Download Maple code" },
+ { mp->email, "EMAIL", "emailicon.gif", 'e', "E-mail to a colleague" },
+ { NULL, NULL, NULL, 0, NULL }
+ };
+
+ puts("<p class=\"options\">");
+ for (op = o; op->str != NULL; ++op) {
+ if (*op->str != '\0') {
+ printf("<a href=\"%s?id=%u&amp;jump=%c\">", sname, mp->id, op->trg);
+ printf("<img alt=\"%s\" src=\"/%s/%s\" /> ", op->alt, "images", op->img);
+ printf("%s</a><br />\n", op->dsc);
+ }
+ }
+ puts("</p>");
+}
+
+char *
+pr_lang(char *lang)
+{
+ char l[3];
+
+ struct {
+ char *lang;
+ char *img;
+ char *name;
+ } *lp, language[] = {
+ { "en", "uk_small.png", "English" },
+ { "de", "germany_small.png", "Deutsch" },
+ { "fr", "france_small.png", "Francaise" },
+ { "ru", "ussr_small.png", "Russian" },
+ { NULL, NULL, NULL }
+
+ };
+
+ l[0] = tolower(lang[0]);
+ l[1] = tolower(lang[1]);
+ l[2] = '\0';
+
+ for (lp = language; lp->lang != NULL; ++lp) {
+ if (strncmp(lang, lp->lang, 2) == 0)
+ break;
+ }
+
+ if (lp->lang == NULL)
+ lp = language;
+
+ printf("<img alt=\"%s\" src=\"/flags/%s\" />\n", lp->name, lp->img);
+
+ return lp->name;
+}
+
+void
+pr_record(struct meta *mp, size_t n, enum sorder curso)
+{
+ int i = 0;
+ char *uri, *p;
+
+ uri = getenv("REQUEST_URI");
+
+ /* HACK: strip all args exept the first */
+ if ((p = strchr(uri, '&')) != NULL)
+ *p = '\0';
+
+ puts("<table>");
+ puts("<tr>");
+ printf("<th><a href=\"%s&amp;%c=t\">Title</a></th>\n", uri, curso == TITLEI ? 'd' : 'a');
+ puts("<th>Language</th>");
+ puts("<th>Options</th>");
+ printf("<th><a href=\"%s&amp;%c=d\">Date Publlished</a></th>\n", uri, curso == DATEI ? 'd' : 'a');
+ printf("<th><a href=\"%s&amp;%c=a\">Author</a></th>\n", uri, curso == AUTHORI ? 'd' : 'a');
+ puts("</tr>");
+
+ for (; n--; ++mp) {
+ if (mp->type == M_RECORD) {
+ printf("<tr class=\"%s\"><td>", (i++ & 1) == 0 ? "odd" : "even");
+ printf("<h4><a href=\"%s?id=%u\">%s</a></h4>\n", sname, mp->id, mp->title);
+ if (*mp->abstract != '\0')
+ printf("<blockquote>%s</blockquote>\n", mp->abstract);
+ puts("</td><td>");
+ pr_lang(mp->language);
+ puts("</td><td>");
+ pr_opts(mp);
+ puts("</td>");
+ printf("<td>%s</td>\n", ctime(&mp->date));
+ printf("<td>%s</td></tr>\n", mp->author);
+ }
+ }
+
+ puts("</table>");
+}
+
+#if 0
+void
+pr_image(struct meta *mp, size_t n)
+{
+ puts("<div class=\"image\">");
+ printf("<img src=\"/%s/", datadir);
+ while (--n)
+ printf("%s/", (++mp)->dir);
+ printf("%s\" />", mp->img);
+ puts("</div>");
+}
+#endif
+
+void
+pr_new(size_t max)
+{
+ struct meta *mp;
+ size_t n;
+
+ mp = db_find("", &n);
+ if (mp == NULL)
+ return;
+
+ db_sort(mp, n, DATED);
+
+ for (; n-- && max; ++mp) {
+ if (mp->type == M_RECORD) {
+ puts("<p>");
+ printf("<a href=\"%s?id=%u\">%s</a><br />\n", sname, mp->id, mp->title);
+ puts(ctime(&mp->date));
+ puts("</p>");
+ --max;
+ }
+ }
+}
+
+int
+have(struct meta *mp, size_t n, enum mtype t)
+{
+ while (n--)
+ if ((mp++)->type == t)
+ return 1;
+ return 0;
+}
+
+__dead void
+jmp(struct meta *mp, size_t n, enum jflag jf)
+{
+ char *p[16];
+
+ printf("Location: http://%s/%s/", getenv("SERVER_NAME"), datadir);
+ while (--n)
+ printf("%s/", (++mp)->dir);
+
+ p[0] = mp->html;
+ p[1] = mp->pdf;
+ p[2] = mp->mws;
+ p[3] = mp->mw;
+ p[4] = mp->code;
+ p[5] = mp->email;
+ p[6] = mp->img;
+
+ printf("%s\n\n", p[jf]);
+
+ exit(0);
+}
+
+__dead void
+mailto(unsigned int id)
+{
+ struct meta m;
+
+ if (db_get(&m, id) != NULL)
+ printf("Location: mailto:%s\n\n", m.email);
+
+ exit(0);
+}
+
+
+int
+main(int argc, char **argv)
+{
+ struct meta *curr, *chld, *path, *found;
+ size_t nchld, npath, nfound;
+ unsigned int id;
+ enum jflag jf;
+ enum sorder so;
+ char *q, *srchq, *lang;
+
+ sname = getenv("SCRIPT_NAME");
+
+ id = 0;
+ if ((q = getquery("id")) != NULL) {
+ id = atoll(q);
+ free(q);
+ }
+
+ jf = J_NONE;
+ if ((q = getquery("jump")) != NULL) {
+ switch (*q) {
+ case 'h': jf = J_HTML; break;
+ case 'p': jf = J_PDF; break;
+ case 's': jf = J_MWS; break;
+ case 'm': jf = J_MW; break;
+ case 'c': jf = J_CODE; break;
+ case 'e': jf = J_EMAIL; break;
+ case 'i': jf = J_IMG; break;
+ }
+ free(q);
+ }
+
+ so = TITLEI;
+ if ((q = getquery("a")) != NULL) {
+ switch (*q) {
+ case 'a': so = AUTHORI; break;
+ case 'd': so = DATEI; break;
+ case 't': so = TITLEI; break;
+ }
+ free(q);
+ } else if ((q = getquery("d")) != NULL) {
+ switch (*q) {
+ case 'a': so = AUTHORD; break;
+ case 't': so = TITLED; break;
+ case 'd': so = DATED; break;
+ }
+ free(q);
+ }
+
+ if (db_open(O_RDONLY) != 0)
+ exit(0);
+
+ found = NULL;
+ srchq = NULL;
+ if ((q = getquery("search")) != NULL) {
+ srchq = decode(q);
+ found = db_find(srchq, &nfound);
+ free(q);
+ }
+
+ curr = db_get(NULL, id);
+ chld = db_children(id, &nchld);
+ path = db_path(id, &npath);
+
+ if (jf != J_NONE && path != NULL)
+ jmp(path, npath, jf);
+ /* NOTREACHED */
+
+ puts("Content-type: text/html; charset=iso-8859-1;\n");
+
+ puts("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"");
+ puts("\t\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
+ puts("<!-- $Id$ -->");
+
+ if (curr == NULL) {
+
+ puts("<html>");
+#if 0
+ printf("<h1> %s has just experienced an error</h1>", getenv("SERVER_NAME"));
+ puts("<p>Our technical team has been notified of the issue.");
+ puts("Please refresh the page or use the back button to return to the site.</p>");
+#else
+ puts("<h1>oops</h1>");
+ printf("id %u doesn't exist, try another number ;-)", id);
+#endif
+ puts("</html>");
+ exit(0);
+ }
+
+ pr_head(curr);
+
+ if (id != 0 && path != NULL)
+ pr_path(path, npath);
+
+ puts("<div class=\"content\">");
+
+ if (srchq != NULL) {
+ if (found != NULL) {
+ puts("<h2>Search results for:");
+ printf("<a href=\"%s?search=%s\">%s</a></h2>\n", sname, srchq, srchq);
+ db_sort(found, nfound, so);
+ if (have(found, nfound, M_SET)) {
+ puts("<h2>Sections</h2>");
+ pr_set(found, nfound);
+ }
+ if (have(found, nfound, M_RECORD)) {
+ puts("<h2>Content</h2>");
+ pr_record(found, nfound, so);
+ }
+ free(q);
+ } else {
+ puts("<h2>Nothing found for:");
+ printf("<a href=\"%s?search=%s\">%s</a></h2>\n", sname, srchq, srchq);
+ }
+ } else {
+ if (id == 0) {
+ puts("<div class=\"right\">");
+ puts("<h3>Recent</h3>");
+ pr_new(SHOWNEW);
+ puts("</div>");
+ }
+
+ if (chld != NULL) {
+ if (*curr->abstract != '\0')
+ printf("<p>%s</p>\n", curr->abstract);
+ db_sort(chld, nchld, so);
+ if (have(chld, nchld, M_SET)) {
+ printf("<h2>%sections</h2>", (id == 0) ? "S" : "Subs");
+ pr_set(chld, nchld);
+ }
+ if (have(chld, nchld, M_RECORD)) {
+ puts("<h2>Content</h2>");
+ pr_record(chld, nchld, so);
+ }
+ } else if (curr->type == M_RECORD) {
+ if (*curr->img != '\0') {
+ puts("<div class=\"image\">");
+ printf("<img alt=\"illustration\" src=\"%s?id=%u&amp;jump=img\" />", sname, curr->id);
+ puts("</div>");
+ }
+
+ puts("<div class=\"right\">");
+ puts("<h3>Options</h3>");
+ pr_opts(curr);
+ puts("</div>");
+
+ if (*curr->abstract != '\0')
+ printf("<p>%s</p>\n", curr->abstract);
+
+ puts("<p>");
+ printf("Author: %s<br />\n", curr->author);
+ printf("Date: %s<br />\n", ctime(&curr->date));
+ printf("Language: ");
+ lang = pr_lang(curr->language);
+ printf("%s\n", lang);
+ puts("</p>");
+ } else if (curr->type == M_SET) {
+ if (*curr->abstract != '\0')
+ printf("<p>%s</p>\n", curr->abstract);
+ } else {
+ puts("oops");
+ }
+
+ }
+
+ puts("</div>");
+
+ pr_foot();
+
+ db_close();
+
+ return 0;
+}