From 32f034bb8016b17cefd0e80caec19fa75d6503bb Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Tue, 9 Oct 2012 15:55:35 -0500 Subject: [PATCH 1/7] move to roundcube --- derby/derby.mk | 6 ++++- derby/index.mdwn | 6 ++--- ilohamail.cgi.c | 25 ++++++++++++++++++ index.mdwn | 27 +++++++++++++++++++ mail.cgi.c | 68 ++++++++++++++++++++++++++++++++++++++++++------ woozle.mk | 4 +-- 6 files changed, 122 insertions(+), 14 deletions(-) create mode 100644 ilohamail.cgi.c diff --git a/derby/derby.mk b/derby/derby.mk index 00a2c20..423692e 100644 --- a/derby/derby.mk +++ b/derby/derby.mk @@ -1 +1,5 @@ -PLAIN += $(wildcard derby/*.mdwn) +PLAIN += derby +COPY += derby/scrimmage.pdf + +$(DESTDIR)/derby/scrimmage.pdf: derby/scrimmage.ps + ps2pdf $< $@ diff --git a/derby/index.mdwn b/derby/index.mdwn index 45cde85..63064f8 100644 --- a/derby/index.mdwn +++ b/derby/index.mdwn @@ -13,9 +13,9 @@ The Woozle Promise Software -------- -* [Scoreboard](/scoreboard/), works in any web browser -* [Penalty Timer (Android)](https://play.google.com/store/apps/details?id=org.woozle.penaltytimer) -* [Track](/track/) with movable players +* [Scoreboard](/scoreboard/), works in any web browser -- [source](http://woozle.org/~neale/g.cgi/scoreboard/) +* [Penalty Timer for Android](https://play.google.com/store/apps/details?id=org.woozle.penaltytimer) -- [source](http://woozle.org/~neale/g.cgi/ptimer/) +* [Track](/track/) with movable players -- [source](http://woozle.org/~neale/g.cgi/track/) Forms ----- diff --git a/ilohamail.cgi.c b/ilohamail.cgi.c new file mode 100644 index 0000000..3c7924f --- /dev/null +++ b/ilohamail.cgi.c @@ -0,0 +1,25 @@ +#include +#include +#include +#include + +const char *basepath = "/usr/share/IlohaMail/source"; + +int +main(int argc, char *argv[]) +{ + char *pathinfo = getenv("PATH_INFO"); + char filename[512]; + + if ((! pathinfo) || + (! strcmp(pathinfo, "/")) || + (0 == strcmp(pathinfo, "/index.html"))) { + pathinfo = "/index.php"; + } + snprintf(filename, sizeof filename, "%s%s", basepath, pathinfo); + setenv("SCRIPT_FILENAME", filename, 1); + setenv("REDIRECT_STATUS", "fuck me", 1); + execl("/usr/bin/php-cgi", filename, NULL); + + return 0; +} diff --git a/index.mdwn b/index.mdwn index c8d3db6..c1f4bb2 100644 --- a/index.mdwn +++ b/index.mdwn @@ -7,3 +7,30 @@ held by folks who know the right person to ask. + +October 9: New Webmail +---------------------- + +The October 2 change broke webmail. Again. Rather than fix it again, +I thought everyone would enjoy a more modern webmail client. You can +still get to [the old one](https://woozle.org/ilohamail.cgi) if you +want to pull your address book out or something, but I'm planning on +removing it in a few months unless someone asks me not to. + +Mail filtering is now available. You can +get to that under Settings. This uses a standard filtering language, +so your filters will stick around if I have to change the webmail +program again. These filters also apply to IMAP clients (like your +Android or iPhone, or Thunderbird). + + + +October 2: Kerboom +------------------ + +In trying to get my 2006 cell phone to sync with Google Calendar, I broke +(among other things) mail. I think it's all back up now. If you see any +other problems, please give me a call. + +I should mention that [eris HTTPd](http://woozle.org/~neale/src/eris.html) +was the only service that never went down; not even for a nanosecond. diff --git a/mail.cgi.c b/mail.cgi.c index ea9df69..f182565 100644 --- a/mail.cgi.c +++ b/mail.cgi.c @@ -3,22 +3,74 @@ #include #include -const char *basepath = "/usr/share/IlohaMail/source"; +const char *baseurl = "https://woozle.org/mail.cgi/"; +const char *basepath = "/opt/roundcubemail"; int main(int argc, char *argv[]) { char *pathinfo = getenv("PATH_INFO"); + char *remaddr = getenv("REMOTE_ADDR"); + size_t pathlen = pathinfo?strlen(pathinfo):0; char filename[512]; + char *ext; - if ((! pathinfo) || - (! strcmp(pathinfo, "/")) || - (0 == strcmp(pathinfo, "/index.html"))) { - pathinfo = "/index.php"; + if ((! pathinfo) || (! remaddr) || (0 != strncmp(remaddr, "127.0.0.1:", 10))) { + printf("%s\n", baseurl); + return 0; + } else if (0 == strcmp(pathinfo, "/index.html")) { + snprintf(filename, sizeof filename, "%s/index.php", basepath); + } else if (pathinfo[pathlen-1] == '/') { + snprintf(filename, sizeof filename, "%s%sindex.php", basepath, pathinfo); + } else { + snprintf(filename, sizeof filename, "%s%s", basepath, pathinfo); } - snprintf(filename, sizeof filename, "%s%s", basepath, pathinfo); - setenv("SCRIPT_FILENAME", filename, 1); - execl("/usr/bin/php-cgi", filename, NULL); + + ext = strrchr(filename, '.'); + if (! ext) { + ext = ""; + } + + if (0 == strcmp(ext, ".php")) { + setenv("SCRIPT_FILENAME", filename, 1); + setenv("REDIRECT_STATUS", "fuck me", 1); + execl("/usr/bin/php-cgi", filename, NULL); + } else if (strstr(filename, "/config/") || + strstr(filename, "/logs/") || + strstr(filename, "/temp/")) { + printf("Content-type: text/plain\n\n[MESSAGE REDACTED]\n"); + } else { + FILE *f = fopen(filename, "r"); + char *ct = "application/octet-stream"; + + if (0 == strcmp(ext, ".css")) { + ct = "text/css"; + } else if (0 == strcmp(ext, ".html")) { + ct = "text/html"; + } else if (0 == strcmp(ext, ".js")) { + ct = "application/javascript"; + } else if (0 == strcmp(ext, ".png")) { + ct = "image/png"; + } else if (0 == strcmp(ext, ".jpg")) { + ct = "image/jpeg"; + } else if (0 == strcmp(ext, ".gif")) { + ct = "image/gif"; + } + + printf("Content-type: %s\n\n", ct); + + while (! feof(f)) { + char buf[4096]; + size_t len; + + + len = fread(buf, 1, sizeof buf, f); + if (len) { + fwrite(buf, 1, len, stdout); + } + } + } + fflush(stdout); return 0; } diff --git a/woozle.mk b/woozle.mk index 3570b8c..161d8c2 100644 --- a/woozle.mk +++ b/woozle.mk @@ -1,11 +1,11 @@ PLAIN += . COPY += icon.png style.css style-black.css lists.cgi wishlist.cgi set.cgi $(TEMPLATE) -COPY += mail.cgi +COPY += mail.cgi ilohamail.cgi COPY += google7f698b9893809122.html HTML += people.html $(DESTDIR)/people.html: people.sh template.html.m4 sh $< | $(MDWNTOHTML) > $@ -$(DESTDIR)/mail.cgi: mail.cgi.c +$(DESTDIR)/%.cgi: %.cgi.c $(CC) -Wall -Werror -o $@ $< From 555afad4434c9b96ecf29c5f06e9559b73a9bef0 Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Tue, 9 Oct 2012 16:17:02 -0500 Subject: [PATCH 2/7] remove unneeded fflush --- mail.cgi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/mail.cgi.c b/mail.cgi.c index f182565..93f7643 100644 --- a/mail.cgi.c +++ b/mail.cgi.c @@ -70,7 +70,6 @@ main(int argc, char *argv[]) } } } - fflush(stdout); return 0; } From c947e9983c0b8fef5be7b58b952742bfec2085cf Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Mon, 29 Oct 2012 12:15:50 -0500 Subject: [PATCH 3/7] Make homepages without tildes, too --- people.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/people.sh b/people.sh index 62ac05b..e693d69 100755 --- a/people.sh +++ b/people.sh @@ -8,8 +8,11 @@ echo ls /home/*/public_html/index.html | while read fn; do a=${fn#/home/} u=${a%/public_html/index.html} - l=/srv/www/woozle.org/~$u + tl=/srv/www/woozle.org/~$u + l=/srv/www/woozle.org/$u echo "* [$u](/~$u/)" - [ -h $l ] || ln -s /home/$u/public_html $l + for link in $tl $l; do + [ -h $link ] || ln -s /home/$u/public_html $link + done done From 01cc421b04cdd5e0cb8daf407006aca49618e801 Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Tue, 27 Nov 2012 13:30:06 -0600 Subject: [PATCH 4/7] Add l.cgi --- l.cgi.c | 376 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ woozle.mk | 2 +- 2 files changed, 377 insertions(+), 1 deletion(-) create mode 100644 l.cgi.c diff --git a/l.cgi.c b/l.cgi.c new file mode 100644 index 0000000..05ffc88 --- /dev/null +++ b/l.cgi.c @@ -0,0 +1,376 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const char *BASE_DIR = "/tmp/clicko"; +const char *BASE_URL = "http://woozle.org/l.cgi"; + + +#define POST_MAX 1024 + +/* + * CGI + */ +static int is_cgi = 0; +static char **argv = NULL; + +static int +read_char_argv() +{ + static int arg = 0; + static char *p; + + if (NULL == argv) { + return EOF; + } + + if (0 == arg) { + arg = 1; + p = argv[1]; + } + + if (! p) { + return EOF; + } else if (! *p) { + arg += 1; + p = argv[arg]; + return '&'; + } + + return *(p++); +} + +static int +read_char_stdin() +{ + static int inlen = -1; + + if (-1 == inlen) { + char *p = getenv("CONTENT_LENGTH"); + if (p) { + inlen = atoi(p); + if (inlen > POST_MAX) { + inlen = POST_MAX; + } + if (inlen < 0) { + inlen = 0; + } + } else { + inlen = 0; + } + } + + if (inlen) { + inlen -= 1; + return getchar(); + } + return EOF; +} + +static int +read_char_query_string() +{ + static char *p = (char *)-1; + + if ((char *)-1 == p) { + p = getenv("QUERY_STRING"); + } + + if (! p) { + return EOF; + } else if (! *p) { + return EOF; + } else { + return *(p++); + } +} + +static int (* read_char)() = read_char_argv; + +int +cgi_init(char *global_argv[]) +{ + char *rm = getenv("REQUEST_METHOD"); + + if (! rm) { + read_char = read_char_argv; + argv = global_argv; + } else if (0 == strcmp(rm, "POST")) { + read_char = read_char_stdin; + is_cgi = 1; + } else if (0 == strcmp(rm, "GET")) { + read_char = read_char_query_string; + is_cgi = 1; + } else { + printf(("405 Method not allowed\r\n" + "Allow: GET, POST\r\n" + "Content-type: text/plain\r\n" + "\r\n" + "%s is not allowed.\n"), + rm); + return -1; + } + + return 0; +} + +static char +tonum(int c) +{ + if ((c >= '0') && (c <= '9')) { + return c - '0'; + } + if ((c >= 'a') && (c <= 'f')) { + return 10 + c - 'a'; + } + if ((c >= 'A') && (c <= 'F')) { + return 10 + c - 'A'; + } + return 0; +} + +static char +read_hex() +{ + int a = read_char(); + int b = read_char(); + + return tonum(a)*16 + tonum(b); +} + +/* Read a key or a value. Since & and = aren't supposed to appear + outside of boundaries, we can use the same function for both. +*/ +size_t +cgi_item(char *str, size_t maxlen) +{ + int c; + size_t pos = 0; + + while (1) { + c = read_char(); + switch (c) { + case EOF: + case '=': + case '&': + str[pos] = '\0'; + return pos; + case '%': + c = read_hex(); + break; + case '+': + c = ' '; + break; + } + if (pos < maxlen - 1) { + str[pos] = c; + pos += 1; + } + } +} + +void +cgi_head(char *title) +{ + if (is_cgi) { + printf("Content-type: text/html\r\n\r\n"); + } + printf(("\n" + "\n" + " %s\n" + " \n" + "

%s

\n"), + title, title); +} + +void +cgi_foot() +{ + printf("\n" + " \n" + "\n"); +} + +void +cgi_result(int code, char *desc, char *fmt, ...) +{ + va_list ap; + + if (is_cgi) { + printf("%d %s\r\n", code, desc); + } + cgi_head(desc); + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + cgi_foot(); + exit(0); +} + +void +cgi_page(char *title, char *fmt, ...) +{ + va_list ap; + + cgi_head(title); + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + cgi_foot(); + exit(0); +} + +void +cgi_error(char *text) +{ + cgi_result(500, "Internal error", "

%s

", text); +} + + +static FILE * +open_file(char *shorty, char *mode) +{ + char fn[256]; + FILE *f; + + snprintf(fn, sizeof fn, "%s/%s.url", BASE_DIR, shorty); + + f = fopen(fn, mode); + if (! f) { + cgi_error("Unable to open database"); + } + + return f; +} + +void +shorten_url() +{ + char u[4096]; + size_t ulen; + char shorty[16]; + + ulen = cgi_item(u, sizeof u); + if (ulen == 0) { + cgi_error("No URL specified"); + } + + snprintf(shorty, sizeof shorty, "%08x.%04x", (unsigned int)time(NULL), getpid()); + + /* Put the URL into a file */ + { + FILE *f = open_file(shorty, "w"); + fprintf(f, "%s", u); + fclose(f); + } + + /* Report back */ + printf("Content-type: text/plain\r\n\r\n"); + printf("%s/%s\n", BASE_URL, shorty); +} + + +void +redirect(char *pi) +{ + int i; + + if (! pi) { + cgi_error("No short URL provided"); + } + + if (pi[0] != '/') { + cgi_error("Invalid PATH_INFO"); + } + pi += 1; + + for (i = 0; pi[i]; i += 1) { + if ((! isalnum(pi[i])) && + (pi[i] != '.')) { + cgi_error("Bad short URL"); + } + } + + /* Open file */ + { + char u[4096]; + FILE *f = open_file(pi, "r"); + + fgets(u, sizeof u, f); + fclose(f); + + printf("Location: %s\r\n", u); + } +} + + +void +list_links() +{ + char g[256]; + glob_t globbuf; + int i; + + snprintf(g, sizeof g, "%s/*.url", BASE_DIR); + + glob(g, 0, NULL, &globbuf); + + cgi_head("Clicko history"); + printf("
    \n"); + for (i = globbuf.gl_pathc - 1; i >= 0; i -= 1) { + FILE *f = fopen(globbuf.gl_pathv[i], "r"); + char url[4096]; + + fgets(url, sizeof url, f); + fclose(f); + + printf("
  • %s
  • \n", url, url); + } + printf("
\n"); + cgi_foot(); +} + +int +main(int argc, char *argv[]) +{ + if (-1 == cgi_init(argv)) { + fprintf(stderr, "Unable to initialize CGI.\n"); + return -1; + } + + while (1) { + char key[12]; + size_t klen; + + klen = cgi_item(key, sizeof key); + if (klen == 0) { + break; + } + switch (key[0]) { + case 'u': + shorten_url(); + return 0; + } + } + + { + char *pi = getenv("PATH_INFO"); + + if (pi) { + redirect(pi); + } + } + + list_links(); + + return 0; +} diff --git a/woozle.mk b/woozle.mk index 161d8c2..eb2b875 100644 --- a/woozle.mk +++ b/woozle.mk @@ -1,6 +1,6 @@ PLAIN += . COPY += icon.png style.css style-black.css lists.cgi wishlist.cgi set.cgi $(TEMPLATE) -COPY += mail.cgi ilohamail.cgi +COPY += mail.cgi ilohamail.cgi l.cgi COPY += google7f698b9893809122.html HTML += people.html From 8e41ef169d6442c3a788227d43803b502a9691b0 Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Fri, 7 Dec 2012 20:57:02 -0600 Subject: [PATCH 5/7] SSL certificate broken --- index.mdwn | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/index.mdwn b/index.mdwn index c1f4bb2..3d2f6d5 100644 --- a/index.mdwn +++ b/index.mdwn @@ -8,6 +8,28 @@ held by folks who know the right person to ask. ssh fingerprint for woozle.org: 63:ac:b0:e9:ee:9f:a9:4f:55:0a:4a:42:5d:45:47:06 --> +December 7: Expired SSL Certificate +----------------------------------- + +Woozle's SSL certificate expired tonight. It's my own fault: I +thought the warnings were spam. + +I'll have a new SSL certificate in place hopefully before Monday. +In the meantime, you will either have to tell your mail client that it's okay to use the expired certificate, +or if you're not comfortable with that +(I wouldn't blame you), +wait until I can get it fixed. + +I hope to have a new certificate installed by Monday, +but I have to wait for a lot of bureaucracy to churn through my +application so I don't know when, exactly, I will be able +to install a new certificate. +The SSL certificate is one of the few things about woozle that I have little control over. +It also costs me more to buy the certificate than it does to run the entire rest of the machine. + +My apologies. + + October 9: New Webmail ---------------------- @@ -22,15 +44,3 @@ get to that under Settings. This uses a standard filtering language, so your filters will stick around if I have to change the webmail program again. These filters also apply to IMAP clients (like your Android or iPhone, or Thunderbird). - - - -October 2: Kerboom ------------------- - -In trying to get my 2006 cell phone to sync with Google Calendar, I broke -(among other things) mail. I think it's all back up now. If you see any -other problems, please give me a call. - -I should mention that [eris HTTPd](http://woozle.org/~neale/src/eris.html) -was the only service that never went down; not even for a nanosecond. From 1bfc365c762bdb04a60dd82b25261f8488bc8d16 Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Sat, 8 Dec 2012 17:04:44 -0600 Subject: [PATCH 6/7] fix webmail --- index.mdwn | 23 +++++++++++++++++++++++ mail.cgi.c | 4 ++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/index.mdwn b/index.mdwn index 3d2f6d5..9a2a0ff 100644 --- a/index.mdwn +++ b/index.mdwn @@ -8,6 +8,29 @@ held by folks who know the right person to ask. ssh fingerprint for woozle.org: 63:ac:b0:e9:ee:9f:a9:4f:55:0a:4a:42:5d:45:47:06 --> +December 8 pt. 2: Webmail works now +----------------------------------- + +I didn't get a chance to test webmail before I had to run off to an appointment. +It's back up now, near as I can tell. + + +December 8: SSL Certificate Renewed +----------------------------------- + +Woozle now has a new SSL certificate, +thanks to the generous folks at [StartCom](http://www.startssl.com). +I think everything is back to normal. + +If you are having trouble with web, or sending or recieving email, +please *please* let me (Neale) know right away. +Phone or text message is okay. +As far as I can tell, everything's working fine, +and I depend on *you* to tell me otherwise. + + + + December 7: Expired SSL Certificate ----------------------------------- diff --git a/mail.cgi.c b/mail.cgi.c index 93f7643..69923f7 100644 --- a/mail.cgi.c +++ b/mail.cgi.c @@ -15,8 +15,8 @@ main(int argc, char *argv[]) char filename[512]; char *ext; - if ((! pathinfo) || (! remaddr) || (0 != strncmp(remaddr, "127.0.0.1:", 10))) { - printf("%s\n", baseurl); + if ((! pathinfo) || (! remaddr) || (! getenv("HTTPS"))) { + printf("Location: %s\n", baseurl); return 0; } else if (0 == strcmp(pathinfo, "/index.html")) { snprintf(filename, sizeof filename, "%s/index.php", basepath); From 33933febb50cf74c491894127a60a7bfe4da0006 Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Thu, 20 Dec 2012 12:11:54 -0600 Subject: [PATCH 7/7] xmas 2012 letter --- xmas/2012/index.mdwn | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 xmas/2012/index.mdwn diff --git a/xmas/2012/index.mdwn b/xmas/2012/index.mdwn new file mode 100644 index 0000000..bac7da1 --- /dev/null +++ b/xmas/2012/index.mdwn @@ -0,0 +1,16 @@ +Title: 2012 Christmas Letter + +Happy Holidays from Amy, Neale & Ginnie!  We’ve had a really busy but fun 2012.  Ginnie is now in 2nd grade, and we’re finding that every school year seems to have a theme of some sort of learning that she works on more than other things.  This year is definitely the year of being social.  It doesn’t hurt that her best friend lives directly across the street from us and is in the same class she is in, which is a mistake I’m sure the school won’t make when they put together class lists for next year! Ginnie continues to take Irish dance classes and goes to K-Kids once a week, which is a club through Kiwanis that concentrates on community service.  The community service seems to involve a lot of cookies and juice, but she does save a cookie for her mom some days, which could be considered doing the community a favor.  Ginnie is still a total ham and we love her to bits. + +Jada the Dog continues to claim that we don’t feed her enough and definitely don’t give her enough attention or walks.  She has been developing her trick of dragging her dog beds around the house to wherever the family is hanging out and flopping down on them, and she still squeaks her squeaky toys at 7pm sharp.  She is always on the lookout for sheep that need herding.  Dingo is getting pretty gray but is still as high-strung as he ever was.  We think that the mail carriers and meter-readers have figured out that he’s a total pushover, but we haven’t told Dingo that yet. + +Neale is absolutely loving his job and plans to work until he’s 150 years old.  He also loves plumbing.  He loves it so much that he installed the same toilet twice in our remodeled bathroom, just for fun.  Not because it was leaking.  He has become the go-to volunteer for at least two roller derby leagues in our area, and he’ll be Amy’s team’s Head NSO (non-skating official) this coming season.  His computer security training seminars are in the 5th year and still going strong. Neale and Amy went swing dancing for the first time in about 12 years recently, and it was really nice to rediscover how much fun that is! + +Amy is going into her 2nd season of roller derby with the Los Alamos Derby Dames.  They don’t have their season schedule hammered out just yet, but when they do, everyone should come and watch her team play!  And if you can’t do that, at least support your own town’s roller derby league and check out a “bout” sometime! Most leagues are non-profit and raise money for animal shelters, food banks, children’s hospitals and the like.  It’s also just a lot of fun to watch!  Amy also started nursing school in August.  She has three semesters and a lot of hard work left, but so far, so good!  It makes it a lot easier to have such a loving and supportive family in Neale and Ginnie. + +We get to end this letter with news that Amy's sister Kristen is a new mommy: Daphne was born on December 17. Mom and proud daddy Alex are doing great, and we can't wait to go see all three in San Francisco. + +With love from our crazy household to yours, + +Neale, Amy, Ginnie, Jada, Dingo and the gopher in the front yard. +