diff --git a/tmpl/foot.tmpl b/_includes/footer.html similarity index 100% rename from tmpl/foot.tmpl rename to _includes/footer.html diff --git a/tmpl/head.tmpl b/_layouts/head.tmpl similarity index 100% rename from tmpl/head.tmpl rename to _layouts/head.tmpl diff --git a/tmpl/mdwntohtml b/_layouts/mdwntohtml similarity index 100% rename from tmpl/mdwntohtml rename to _layouts/mdwntohtml diff --git a/css/default.css b/assets/css/default.css similarity index 100% rename from css/default.css rename to assets/css/default.css diff --git a/css/font-awesome.css b/assets/css/font-awesome.css similarity index 100% rename from css/font-awesome.css rename to assets/css/font-awesome.css diff --git a/css/font-awesome.min.css b/assets/css/font-awesome.min.css similarity index 100% rename from css/font-awesome.min.css rename to assets/css/font-awesome.min.css diff --git a/css/format.css b/assets/css/format.css similarity index 100% rename from css/format.css rename to assets/css/format.css diff --git a/css/print.css b/assets/css/print.css similarity index 100% rename from css/print.css rename to assets/css/print.css diff --git a/fonts/FontAwesome.otf b/assets/fonts/FontAwesome.otf similarity index 100% rename from fonts/FontAwesome.otf rename to assets/fonts/FontAwesome.otf diff --git a/fonts/fontawesome-webfont.eot b/assets/fonts/fontawesome-webfont.eot similarity index 100% rename from fonts/fontawesome-webfont.eot rename to assets/fonts/fontawesome-webfont.eot diff --git a/fonts/fontawesome-webfont.svg b/assets/fonts/fontawesome-webfont.svg similarity index 100% rename from fonts/fontawesome-webfont.svg rename to assets/fonts/fontawesome-webfont.svg diff --git a/fonts/fontawesome-webfont.ttf b/assets/fonts/fontawesome-webfont.ttf similarity index 100% rename from fonts/fontawesome-webfont.ttf rename to assets/fonts/fontawesome-webfont.ttf diff --git a/fonts/fontawesome-webfont.woff b/assets/fonts/fontawesome-webfont.woff similarity index 100% rename from fonts/fontawesome-webfont.woff rename to assets/fonts/fontawesome-webfont.woff diff --git a/fonts/fontawesome-webfont.woff2 b/assets/fonts/fontawesome-webfont.woff2 similarity index 100% rename from fonts/fontawesome-webfont.woff2 rename to assets/fonts/fontawesome-webfont.woff2 diff --git a/images/StarWarsPowerPoint.jpg b/assets/images/StarWarsPowerPoint.jpg similarity index 100% rename from images/StarWarsPowerPoint.jpg rename to assets/images/StarWarsPowerPoint.jpg diff --git a/images/astro-scale.gif b/assets/images/astro-scale.gif similarity index 100% rename from images/astro-scale.gif rename to assets/images/astro-scale.gif diff --git a/images/bg.jpg b/assets/images/bg.jpg similarity index 100% rename from images/bg.jpg rename to assets/images/bg.jpg diff --git a/images/bg.xcf b/assets/images/bg.xcf similarity index 100% rename from images/bg.xcf rename to assets/images/bg.xcf diff --git a/images/bobsqu.png b/assets/images/bobsqu.png similarity index 100% rename from images/bobsqu.png rename to assets/images/bobsqu.png diff --git a/images/bugs-florida.gif b/assets/images/bugs-florida.gif similarity index 100% rename from images/bugs-florida.gif rename to assets/images/bugs-florida.gif diff --git a/images/carbusbike.gif b/assets/images/carbusbike.gif similarity index 100% rename from images/carbusbike.gif rename to assets/images/carbusbike.gif diff --git a/images/carbusbike.jpg b/assets/images/carbusbike.jpg similarity index 100% rename from images/carbusbike.jpg rename to assets/images/carbusbike.jpg diff --git a/face.png b/assets/images/face.png similarity index 100% rename from face.png rename to assets/images/face.png diff --git a/images/facebook-flowchart.png b/assets/images/facebook-flowchart.png similarity index 100% rename from images/facebook-flowchart.png rename to assets/images/facebook-flowchart.png diff --git a/images/gas-tax.jpg b/assets/images/gas-tax.jpg similarity index 100% rename from images/gas-tax.jpg rename to assets/images/gas-tax.jpg diff --git a/images/haderp.svg b/assets/images/haderp.svg similarity index 100% rename from images/haderp.svg rename to assets/images/haderp.svg diff --git a/images/itsits.png b/assets/images/itsits.png similarity index 100% rename from images/itsits.png rename to assets/images/itsits.png diff --git a/images/not_this_shit_again.jpg b/assets/images/not_this_shit_again.jpg similarity index 100% rename from images/not_this_shit_again.jpg rename to assets/images/not_this_shit_again.jpg diff --git a/images/obama-birthcert.png b/assets/images/obama-birthcert.png similarity index 100% rename from images/obama-birthcert.png rename to assets/images/obama-birthcert.png diff --git a/images/odds-dying.jpg b/assets/images/odds-dying.jpg similarity index 100% rename from images/odds-dying.jpg rename to assets/images/odds-dying.jpg diff --git a/images/orient.png b/assets/images/orient.png similarity index 100% rename from images/orient.png rename to assets/images/orient.png diff --git a/images/pigeon.gif b/assets/images/pigeon.gif similarity index 100% rename from images/pigeon.gif rename to assets/images/pigeon.gif diff --git a/images/starwarsplan.jpg b/assets/images/starwarsplan.jpg similarity index 100% rename from images/starwarsplan.jpg rename to assets/images/starwarsplan.jpg diff --git a/images/viffer.jpg b/assets/images/viffer.jpg similarity index 100% rename from images/viffer.jpg rename to assets/images/viffer.jpg diff --git a/images/wings.jpg b/assets/images/wings.jpg similarity index 100% rename from images/wings.jpg rename to assets/images/wings.jpg diff --git a/images/yurt.png b/assets/images/yurt.png similarity index 100% rename from images/yurt.png rename to assets/images/yurt.png diff --git a/g.cgi.go b/g.cgi.go deleted file mode 100644 index e35b835..0000000 --- a/g.cgi.go +++ /dev/null @@ -1,108 +0,0 @@ -package main - -import ( - "bufio" - "crypto/md5" - "fmt" - "log" - "os" - "os/exec" - "strings" -) - -// printf "USER:PASS" | base64 | while read a; do printf "%s" "$a" | md5sum; done -const AuthFilename = "/home/neale/.config/g.cgi/authorization" -const GitProjectRoot = "/home/neale/projects" - -func execv(name string, arg ...string) { - c := exec.Command(name, arg...) - c.Stdin = os.Stdin - c.Stdout = os.Stdout - c.Stderr = os.Stderr - if err := c.Run(); err != nil { - log.Print(err) - } -} - -func Authenticated() bool { - auth := os.Getenv("HTTP_AUTHORIZATION") - if auth == "" { - return false - } - - // Build up a string to match - parts := strings.Split(auth, " ") - switch { - case len(parts) != 2: - return false - case parts[0] != "Basic": - return false - } - - hash := md5.Sum([]byte(parts[1])) - hashhex := fmt.Sprintf("%x", hash) - - authfile, err := os.Open(AuthFilename) - if err != nil { - log.Fatal(err) - } - defer authfile.Close() - - scanner := bufio.NewScanner(authfile) - for scanner.Scan() { - line := scanner.Text() - if line == "" || strings.HasPrefix(line, "#") { - continue; - } - if line == hashhex { - os.Setenv("AUTH_TYPE", parts[0]) - os.Setenv("REMOTE_USER", "XXX-neale") - return true - } - } - - return false -} - -func notice() { - fmt.Println("Content-type: text/html") - fmt.Println() - fmt.Println("") - fmt.Println("") - fmt.Println("Neale's Projects have Moved") - fmt.Println("") - fmt.Println("") - fmt.Println("

Neale's Projects have Moved

") - fmt.Println("I've moved most of my stuff to") - fmt.Println("Github.") - fmt.Println("

") - fmt.Println("X11 things may now be in the") - fmt.Println("9wm team.") - fmt.Println("

") - fmt.Println("Network security things may now be in the") - fmt.Println("dirtbags team.") - fmt.Println("") -} - -func main() { - log.SetFlags(0) - //log.SetOutput(os.Stdout) - //log.SetPrefix("Status: 500 CGI Go Boom\nContent-type: text/plain\n\nERROR: ") - - uri := os.Getenv("REQUEST_URI") - switch { - case strings.HasSuffix(uri, "git-upload-pack") || strings.HasSuffix(uri, "git-receive-pack"): - if Authenticated() { - os.Setenv("GIT_PROJECT_ROOT", GitProjectRoot) - execv("git", "http-backend") - } else { - fmt.Println("Status: 401 Not Authorized") - fmt.Println("Content-type: text/plain") - fmt.Println("WWW-Authenticate: Basic realm=\"git\"") - fmt.Println() - fmt.Println("Nope", os.Getenv("HTTP_AUTHORIZATION")) - } - default: - notice() - } -} diff --git a/src/9wm/9wm.mk b/src/9wm/9wm.mk deleted file mode 100644 index 3544869..0000000 --- a/src/9wm/9wm.mk +++ /dev/null @@ -1 +0,0 @@ -COPY += src/9wm/9wm.png diff --git a/src/9wm/9wm.png b/src/9wm/9wm.png deleted file mode 100644 index 0e633ac..0000000 Binary files a/src/9wm/9wm.png and /dev/null differ diff --git a/src/9wm/index.md b/src/9wm/index.md deleted file mode 100644 index 32a16e2..0000000 --- a/src/9wm/index.md +++ /dev/null @@ -1,54 +0,0 @@ -Title: 9wm -Author: Neale Pickett - -9wm is an X11 window manager inspired by the Plan 9 window manager 8½. -It provides a very simple and clean user interface. -It makes heavy use of the mouse, and no use of the keyboard. -It is click-to-type. -It uses the X11 font system (which, unfortunately, means no Unicode support). - -9wm does not provide virtual desktops, customization, key bindings, -or compositing. -It does not allocate any colors, -and only requires Xlib, -both of which will be great news if you are in 1993. - -9wm is distributed under [an MIT License](https://github.com/nealey/9wm/blob/master/LICENSE.md), -at . - - -How do I use it? -================ - -![Screenshot](9wm.png) - -The focused window has a black border. -Mouse and keyboard events go to this window. -Left click a non-focused window (white border) to focus it. - -Right-click anywhere other than the focused window, -including in any non-focused window, -to bring up a menu. -All further actions are done with the right mouse button. -The menu has options for: - -* New: launch a new xterm -* Reshape: select a window, draw new rectangle for its size -* Move: drag a window around -* Delete: kill (close) a window -* Hide: hide (iconify) a window - -Beneath the first 5 items are a list of all hidden windows. - -Middle-click anywhere other than the focused window -to run "mm mouse2". -It's up to you to write an "mm" program and put it in your path somewhere, -if you want to use this for something. -I have mine run "google-chrome-stable --show-app-list". - - -More Information -================ - -More information can be found in the -[README](https://github.com/nealey/9wm/blob/master/README.md). diff --git a/src/dwm/dwm.mk b/src/dwm/dwm.mk deleted file mode 100644 index 2acbc72..0000000 --- a/src/dwm/dwm.mk +++ /dev/null @@ -1,10 +0,0 @@ -TARGETS += $(DESTDIR)/src/dwm/config.h $(DESTDIR)/src/dwm/status.sh -TARGETS += $(DESTDIR)/src/dwm/dwm-button.sh - -$(DESTDIR)/src/dwm/config.h: $(HOME)/src/ports/dwm/config.h - @mkdir -p $(@D) - cp $< $@ - -$(DESTDIR)/src/dwm/%.sh: $(HOME)/bin/% - @mkdir -p $(@D) - cp $< $@ diff --git a/src/dwm/index.md b/src/dwm/index.md deleted file mode 100644 index 5df8fc0..0000000 --- a/src/dwm/index.md +++ /dev/null @@ -1,26 +0,0 @@ -Title: dwm hacks - -I seem to have trouble keeping my attention on the task at hand if there -are little things flashing in the corner of the screen, or even changing -color (like, "you have new email"). The less I have on the screen, the -more productive I seem to be. It is for this reason that I've been -using "tiling" window managers since about 2003. - -I've been using [dwm](http://dwm.suckless.org/) since a friend -introduced me to it around 2008. What I like most about dwm, aside from -helping me stay focused on the task at hand, is that it gets out of my -way. There are no buttons to click, and no windows to drag around or -resize. In fact, I hardly ever use the mouse anymore, outside of my web -browser. - -* [My config.h](config.h) contains a few features I've added, like - restarting dwm, multimedia buttons, and - [xss](http://woozle.org/~neale/src/xss.html) integration (3 lines of - code). -* [My status program](http://woozle.org/~neale/g.cgi/status) - is responsible for having DWM show the - current time, load average, battery charge, and wifi status. It - gracefully handles machines that lack one or more of these features. -* [My button script](dwm-button.sh) is invoked when a multimedia button - is pressed, and handles screen brightness, volume, external monitors, - and more. diff --git a/src/eguile/eguile.scm b/src/eguile/eguile.scm deleted file mode 100755 index fcd0c6a..0000000 --- a/src/eguile/eguile.scm +++ /dev/null @@ -1,140 +0,0 @@ -#! /usr/bin/guile \ ---debug -e eguile-main -s -!# - -;; eguile -- embedded guile preprocessor -;; Copyright (C) 2002 Neale Pickett -;; -;; This program is free software; you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation; either version 2 of the -;; License, or (at your option) any later version. -;; -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with this program; if not, write to the Free Software -;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -;; 02111-1307 USA - - -(use-modules (ice-9 slib)) - -(require 'fluid-let) -(require 'string-search) -(require 'object->string) - -;; -;; Backwards compatibility. Set this to: -;; -;; 'escm for escm compatibility -;; number for old eguile compatibility -;; -;; Anything else gets you no backwards compatibility -- you get to do -;; things the current way. -;; -(define eguile-compatibility 'current) - -;; Retrieve a named parameter with optional default -(define (getparam args name . default) - (define (loop args) - (cond - ((null? args) - (if (pair? default) - (car default) - #f)) - ((equal? (car args) name) - (cadr args)) - (else - (loop (cddr args))))) - (loop args)) - - -(define lmatch '()) -(define rmatch '()) - -;; -;; New^3 improved parser! Woo woo woo! -;; -(define (stml->commands inp) - (define (loop inp needle other buf) - ;; Read in a line, looking for needle. If it's there, switch needle - ;; and other, and outbuf buf + line - (let ((line (read-line inp 'concat))) - (cond - ((eof-object? line) (cons buf '(""))) - (else - (let ((pos (substring? needle line))) - (cond - (pos - (unread-string (substring line - (+ (string-length needle) - pos)) - inp) - (cons (string-append buf (substring line 0 pos)) - (loop inp other needle ""))) - (else - (loop inp needle other (string-append buf line))))))))) ; Ha ha, scheme - - (define (list->commands list) - ;; Convert the output of (loop) to something that can be evaled. - (cond - ((null? list) "") - ((null? (cdr list)) - (string-append "Unbalanced preprocessor directives: " - (object->string list))) - (else - (let ((str (object->string (car list))) - (expr (cadr list)) - (rest (list->commands (cddr list)))) - (string-append " (display " - (object->string (car list)) - ") " - (cond - ((equal? (substring? ":d " expr) 0) - (string-append "(display " - (substring expr 3) - ")")) - (else - expr)) - rest))))) - - (list->commands - (loop inp "" ""))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(define *program-name* #f) ; Dynamically bound -(define *input-file* #f) ; Dynamically bound -(define *output-file* #f) ; Dynamically bound - -(define (eguile-port inp) - (let ((commands (stml->commands inp))) - (eval-string commands))) - -(define (eguile-file input) - (fluid-let ((*input-file* input)) - (eguile-port (open-input-file input)))) - -(define (eguile input output) - (fluid-let ((*output-file* output)) - (let ((out-port (open-output-file output)) - (*stdout* (current-output-port))) - (set-current-output-port out-port) - (eguile-file input) - (set-current-output-port *stdout*)))) - -(define (eguile-main argv) - ;; Make sure we have the correct number of arguments - (if (not (= (length argv) 3)) - (begin - (display (string-append "Usage: " (car argv) " infile outfile")) - (newline) - (exit))) - - (fluid-let ((*program-name* (car argv))) - ;; Do it to it - (eguile (cadr argv) (caddr argv)))) diff --git a/src/eguile/index.md b/src/eguile/index.md deleted file mode 100644 index 6a66474..0000000 --- a/src/eguile/index.md +++ /dev/null @@ -1,62 +0,0 @@ -Title: Eguile : a scheme preprocessor -Author: Neale Pickett - -If you've ever wished your text preprocessor could do symbolic -derivation, eguile is the tool for you! - -eguile is a preprocessor which lets you include Scheme code in your -source files--any source files, not just HTML. With the bundled -ntp-style.scm, you can give web pages a consistent interface with easy -navigation bars, just like this page. Further functionality is limited -only by your imagination and programming ability. - -eguile looks like PHP, but with Scheme instead of Perl. If you're the -sort of person that would enjoy something like this, you probably don't -need any further description. - - -Downloading it --------------------------- - -[eguile.scm](http://woozle.org/~neale/src/eguile/eguile.scm). - - -Reference --------------------------- - -Easy squeezy: - -

-
<?scm scheme-code ?>
-
Evaluates scheme-code, discarding value of the last expression
- -
<?scm:d scheme-code ?>
-
Evaluates scheme-code, displaying the value of the last expression
-
- -For example: - - - 2 squared is - -renders as: - - 2 squared is 4 - - -Inspiration --------------------------- - -I modeled eguile after ht2html by Barry Warsaw (a far cooler cat than -I). ht2html is a slick package, but it didn't feel enough like -programming to me and seemed more complicated than it needed to be. escm -seemed like a better solution, but felt a little too kludgy, and I -needed to learn Scheme better anyway. So I stole the layout from ht2html -and the syntax from escm. - - -License --------------------------- - -eguile is distributed under the GNU Public License version 2.0 or -later. Please refer to the file COPYING for more information. diff --git a/src/eris.md b/src/eris.md deleted file mode 100644 index b73d2a9..0000000 --- a/src/eris.md +++ /dev/null @@ -1,10 +0,0 @@ -Title: Eris HTTPd - -Eris HTTPd is a small web server to be run from inetd or tcpserver -(tcpsvd in busybox). It is based on -[fnord HTTPd](http://www.fefe.de/fnord/) but shares very little -code in common now. - -* [Eris Versions](/neale/g.cgi/net/eris/) -* [README](/neale/g.cgi/net/eris/about/) - diff --git a/src/escm.md b/src/escm.md deleted file mode 100644 index 2b9cfa2..0000000 --- a/src/escm.md +++ /dev/null @@ -1,54 +0,0 @@ -Title: escm: a scheme preprocessor - -This is my port of [eguile](http://woozle.org/~neale/src/eguile) to -gauche scheme. It uses regular expressions and as a result is faster -and easier to read. It's so tiny, in fact, that I don't feel compelled -to write much about it. - -eguile looks like PHP, but with Scheme instead of Perl. If you're the -sort of person that would enjoy something like this, you probably don't -need any further description. - -I use eguile along with a couple handy procedures and some makefiles to -generate my entire web space, and a few non-profit web sites I maintain. -I'd be happy to share the site-building stuff with anybody who asks, but -I'm not going to package it up until someone's interested. - - -Downloading it --------------- - -You can download a [tarball of the latest version in git](http://woozle.org/~neale/g.cgi/escm/snapshot/escm-master.tar.gz), or check it out yourself: - - git clone http://woozle.org/~neale/repos/escm - - -Reference ---------- - -Easy squeezy: - -
-
<?scm scheme-code ?>
-
Evaluates scheme-code, discarding value of the last expression
- -
<?scm:d scheme-code ?>
-
Evaluates scheme-code, displaying the value of the last expression
-
- -For example: - - - 2 squared is - -renders as: - - 2 squared is 4 - - -Related stuff ------------------------- - -* [escm 1.1](http://practical-scheme.net/vault/escm.html) by Shiro - Kawai, author of gauche, was my inspiration. -* [eguile](http://woozle.org/~neale/src/eguile) is Guile-only diff --git a/src/firebot.md b/src/firebot.md deleted file mode 100644 index bf44595..0000000 --- a/src/firebot.md +++ /dev/null @@ -1,167 +0,0 @@ -Title: Firebot: IRC Automaton - -FireBot is a winner! - -Firebot is an IRC bot combining the functionality of a Linkbot, an -Infobot, and a Clickolinko, which is this cool thing Emad El-Haraty and -I came up with to make short URLs out of stuff posted into the channel, -for people with text browsers that wrap URLs. - -Note that, in addition to interacting with FireBot within a channel, you -can also communicate directly with FireBot via `/msg` commands. Just in -case you need a little one-on-one action and don't want spew your -playtime around some channel with other folks watching. That can be *so* -distracting. Some commands still require you to preface them with -FireBot's name. Example: - - /msg firebot firebot: literal ... - - -Downloading ------------ - -You can download a [tarball snapshot of the latest release](http://woozle.org/~neale/g.cgi/firebot/snapshot/firebot-master.tar.gz), or use cogito: - - git clone http://woozle.org/~neale/projects/firebot - - -LinkBot Features ----------------- - -Firebot can link channels across networks. It is present in all -channels and the same functions can be accessed on either side. -Everything said on one channel is relayed to the others. - -It is possible to link multiple channels on multiple servers, including -multiple channels on a single server. - - - -ClickLinko (UrlBot) -------------------- - -Whenever FireBot sees a URL in the channel, he makes a note of it and -creates a shorter URL out of it. - - - -InfoBot -------- - -As an InfoBot, FireBot listens in the channel for anything of the form -"x is y", and then stores that little tidbit. Later, when someone asks -a question about x ("what is x?", "who is x?", "wtf is x?"), FireBot -answers with the factoid he gathered. - -
-
firebot, **x**
-
look up a factoid for **x**
- -
firebot, **x** is **y**
-
store **y** as a factiod about **x**
- -
firebot, **x** is also **y**
-
store **y** as another factoid about **x**
- -
firebot, append **x** <= **y**
-
store **y** as another factoid about **x**. You'd use this for things where **x** has the word "is" in it, or other things that you can't store with the preceding commands.
- -
no, firebot, **x** is **y**
-
store **y** as the only factoid about **x**, even if **x** already has factoids
- -
firebot, literal **x**
-
display all factoids about **x**
- -
firebot, lock **x**
-
do not learn any more factoids about **x**
- -
firebot, unlock **x**
-
resume learning factoids about **x**
- -
firebot, forget **x**
-
forget all factoids about **x**
- -
firebot, forget **x** from **y**
-
forget a single entry (**x**) that is listed in **y**; **x** can be a single word, it does not need to be the whole entry
- -
firebot, shut up -
make the bot only respond to factoids when addressed specifically
- -
firebot, be chatty -
make the bot respond to factoids even when not addressed
- -
- -In addition, the following tricks can be used within factiods: - -* Any factoid beginning with `\\` (a backslash) is displayed directly. - That is, instead of saying " x is y", FireBot just says - " y". -* Any factoid beginning with : (a colon) is - displayed an action. That is, instead of saying " x is y", - FireBot says "* firebot y" -* You may put `%(sender)s` in the factoid to print the name of the - person who asked about the factoid (when sent to a user in a private - message, it's the recipient of the message) - - - -Utilities ---------- - -
- -
firebot, later tell **whom** **what**
-
The next time **whom** says something in the channel, deliver the message **what** publically.
- -
firebot, in **time** say **what**
-
after **time** (eg. "15 seconds", "2 hours", "5 days"), announce **what** in the channel
- -
seen **whom**
-
Report the last thing said in the channel by **whom**, and how long ago it was said.
- -
dict **word**
-
look **word** up in the dictionary
- -
quote **symbol**
-
get a stock quote for **symbol**
- -
pollen **zip**
-
report pollen forecast for US zip code **zip**
- -
cdecl explain **jibberish**
-
explain the C declaration **jibberish** (eg. "cdecl explain struct bar *(*foo)[](int)")
- -
cdecl declare **english**
-
give the C declaration for **english** (eg. "cdecl declare foo as pointer to array of function (int) returning pointer to struct bar")
- -
how many **x** in **y** **z**
-
determine the number of **x** items that are contained in **y** amount of **z** items (eg. how many miles in 1 light year)
- -
how much is **amt** **source** in **dest**
-
do a currency conversion from **source** to **dest**. Both must be three-letter currency codes. (eg. "how much is 100 USD in EUR")
- -
calc **expr**
-
calculate **expr** (eg. "calc 2 * 5")
- -
- - -Toys ----- - -
- -
8ball, **question**
-
consult the magic 8-ball regarding **question**
- -
**nickname**++
-
add a whuffie point for **nickname**
- -
**nickname**--
-
remove a whuffie point for **nickname**
- -
whuffie for **nickname**
-
check the whuffie for **nickname**
- -
diff --git a/src/index.md b/src/index.md deleted file mode 100644 index f7d7839..0000000 --- a/src/index.md +++ /dev/null @@ -1,32 +0,0 @@ -Title: Software - -I write software for a living. I like doing it so much that sometimes I -even write software just for fun. - - -Current Work ------------- - -* [Runit-Init](/neale/g.cgi/aur/runit-init/about/), an /sbin/init replacement based on busybox -* [Eris HTTPd](/neale/g.cgi/net/eris/about/), a small HTTP (web) server -* [9wm](9wm/), an emulation of the Plan 9 window manager -* [xss](/neale/g.cgi/x11/xss/about/), a suite of X screensaver programs - - -Not-So-Current Work -------------------- - -* [Python IPQueue](ipqueue/), python bindings to Linux libipqueue. It was mentioned in a book and Google Scholar says it's been cited two other times, which makes me *Internet Famous* 😎. -* [eguile](eguile/), like PHP but with Scheme instead. A fork of this is used in gnucash. -* [Woozle Scoreboard](http://woozle.org/scoreboard/), a browser-based roller derby scorebard -* [Hardware Scoreboard](/neale/g.cgi/derby/hw-scoreboard/about/), a microcontroller-based LED roller derby scoreboard -* [Penalty Timer](https://play.google.com/store/apps/details?id=org.woozle.penaltytimer), a roller derby penalty timer for Android -* [Hercules DJ Controller Driver](/neale/g.cgi/hdjd/about/) - - -Even More ---------- - -* [All projects on woozle](/neale/g.cgi/) -* [Github Account](https://github.com/nealey) -* [Gitorious Account](https://gitorious.org/~neale) diff --git a/src/ipqueue/index.md b/src/ipqueue/index.md deleted file mode 100644 index 203a3d5..0000000 --- a/src/ipqueue/index.md +++ /dev/null @@ -1,84 +0,0 @@ -Title: Python ipqueue - -No Longer Maintained --------------------- - -This software is no longer maintained. - -ipqueue has been deprecated in favor of nfqueue. You can download a [Python -nfqueue module](http://software.inl.fr/trac/wiki/nfqueue-bindings) which should -support all the functionality of ipqueue. In Debian or Ubuntu, you can just - - # apt-get install libnetfilter-queue-python - -This page remains here for those who know what they're doing and are -still using the old libipq. This software will not compile with the -backwards-compatibility library provided by nfqueue. - -About ------ - -This is the Netfilter userspace IPQueue module for Python. It allows you -to do all your Linux IPQueue stuff from the comfort of Python. This only -works with Linux. - -Put in simpler terms, this is a way to hook a Python script into your -kernel's networking stack. This could be the fundamental building block -of a firewall. You can use it to snoop on traffic, modify or discard -certain packets, make routing decisions, masquerade stuff, whatever--and -you get it all with garbage collection :) - -Apparently this program appears in a book called "Security Power Tools". -That means I'm *Internet Famous*! - -Download --------- - -This software is no longer maintained (see above). - -* [Latest version](/neale/g.cgi/attic/py-ipqueue/snapshot/py-ipqueue-master.tar.gz) -* [Git repository](/neale/g.cgi/attic/py-ipqueue/) -* [Netfilter QUEUE bindings](nfqueue-0.1.tar.bz2) by Mike Auty -* [nfqueue bindings](http://software.inl.fr/trac/wiki/nfqueue-bindings) - -License -------- - -GPL, of course. - -Support -------- - -This software is no longer maintained (see above). Support requests -will be politely redirected to the newer [nfqueue -bindings](http://software.inl.fr/trac/wiki/nfqueue-bindings). - - -Screen Shots ------------- - -Here's an example program which transparently proxies all traffic it -gets to port 25 of 10.1.1.2. This is just an example, a real-world -transparent proxy would be much more sophisticated. - - #! /usr/bin/env python - - import ipqueue - import iputils - - rewrite = 1 - - q = ipqueue.IPQ(ipqueue.IPQ_COPY_PACKET) - while 1: - p = q.read() - tcp = iputils.TCP(p[ipqueue.PAYLOAD]) - print "Got %s -> %s on hook %d" % (iputils.ntoa(tcp.saddr), - iputils.ntoa(tcp.daddr), - p[ipqueue.HOOK]) - - if rewrite and p[ipqueue.HOOK] == 0: - tcp.daddr = iputils.aton("10.1.1.2") - tcp.th_dport = 25 - q.set_verdict(p[0], ipqueue.NF_ACCEPT, tcp.to_str()) - else: - q.set_verdict(p[0], ipqueue.NF_ACCEPT) diff --git a/src/ipqueue/ipqueue.tar.gz b/src/ipqueue/ipqueue.tar.gz deleted file mode 100644 index 3755e21..0000000 Binary files a/src/ipqueue/ipqueue.tar.gz and /dev/null differ diff --git a/src/ipqueue/nfqueue-0.1.tar.bz2 b/src/ipqueue/nfqueue-0.1.tar.bz2 deleted file mode 100644 index 2702426..0000000 Binary files a/src/ipqueue/nfqueue-0.1.tar.bz2 and /dev/null differ diff --git a/src/misc/9p.scm b/src/misc/9p.scm deleted file mode 100755 index 534dd3c..0000000 --- a/src/misc/9p.scm +++ /dev/null @@ -1,264 +0,0 @@ -#! /usr/bin/gosh - -;; Description: 9p implementation in Scheme -;; Author: Neale Pickett - -;; This uses gauche's networking stuff, but no other gauche stuff. It -;; should be possible to substitute your implementation's networking -;; procedures without too much effort. -(use gauche.net) -(require-extension (srfi 1 4 8 9)) - -(define message-specs - ;; name num format - '((TVersion 100 (2 4 s)) ;x64 - (RVersion 101 (2 4 s)) - (TAuth 102 (2 4 s s)) - (RAuth 103 (2 13)) - (TAttach 104 (2 4 4 s s)) ;x68 - (RAttach 105 (2 13)) - (TError 106 ()) ;illegal - (RError 107 (2 s)) - (TFlush 108 (2 2)) ;x6c - (RFlush 109 (2)) - (TWalk 110 (2 4 4 (2 . s))) - (RWalk 111 (2 (2 . 13))) - (TOpen 112 (2 4 1)) ;x70 - (ROpen 113 (2 13 4)) - (TCreate 114 (2 4 s 4 1)) - (RCreate 115 (2 13 4)) - (TRead 116 (2 4 8 4)) ;x74 - (RRead 117 (2 (4 . d))) - (TWrite 118 (2 4 8 (4 . s))) - (RRwrite 119 (2 4)) - (TClunk 120 (2 4)) ;x78 - (RClunk 121 (2)) - (TRemove 122 (2 4)) - (RRemove 123 (2)) - (TStat 124 (2 4)) ;x7c - (RStat 125 (2 n)) - (TWStat 126 (2 4 n)) - (RWStat 127 (2)))) ;x7f - -(define (spec-by-num num) - (let loop ((specs message-specs)) - (cond - ((null? specs) - #f) - ((equal? (cadar specs) num) - (car specs)) - (else - (loop (cdr specs)))))) - - -;; -;; Helper procedures -;; - -(define (u8-list->uint l) - (let loop ((l (reverse l)) - (acc 0)) - (if (null? l) - acc - (loop (cdr l) - (+ (* 256 acc) - (car l)))))) - -(define (uint->u8-list width i) - (if (zero? width) - '() - (let ((b (modulo i 256)) - (r (floor (/ i 256)))) - (cons b (uint->u8-list (- width 1) r))))) - -;; XXX: s had better be printable 7-bit ASCII -(define (string->u8-list s) - (map char->integer (string->list s))) - -(define (u8-list->string l) - (list->string (map integer->char l))) - - -;; -;; Packing and unpacking, both deal with u8-lists -;; - -(define (pack fmt args) - (let loop ((fmt fmt) - (args args) - (acc '())) - ;;(write (list fmt args acc)) (newline) - (cond - ((null? fmt) - acc) - ((number? (car fmt)) - (loop (cdr fmt) - (cdr args) - (append acc (uint->u8-list (car fmt) (car args))))) - ((equal? (car fmt) 's) - ;;XXX Should handle UTF-8 - (loop (cdr fmt) - (cdr args) - (append acc - (uint->u8-list 2 (string-length (car args))) - (string->u8-list (car args))))) - ((pair? (car fmt)) - ;; fmt item is (c . type), which gets packed to a c-octet n, - ;; followed by n types. - (let ((count (length (car args)))) - (loop (cdr fmt) - (cdr args) - (append acc - (uint->u8-list (caar fmt) count) - (pack (make-list count (cdar fmt)) - (car args)))))) - ((equal? (car fmt) 'n) - ;; XXX: total guess here - (loop (cdr fmt) - (cdr args) - (append acc (car args)))) - (else - (error (format "Unknown format element: ~a" (car fmt))))))) - -(define (unpack fmt l) - (reverse - (let loop ((fmt fmt) - (l l) - (acc '())) - ;;(write (list fmt l acc)) (newline) - (cond - ((null? fmt) - acc) - ((number? (car fmt)) - (loop (cdr fmt) - (drop l (car fmt)) - (cons (u8-list->uint (take l (car fmt))) - acc))) - ((equal? (car fmt) 's) - (let ((len (u8-list->uint (take l 2))) - (m (drop l 2))) - (loop (cdr fmt) - (drop m len) - (cons (u8-list->string (take m len)) - acc)))) - ((pair? (car fmt)) - (let* ((count (u8-list->uint (take l (caar fmt)))) - (m (drop l (caar fmt)))) - (receive (p octets) - (case (cdar fmt) - ((s) - (let ((p (reverse (unpack (make-list count (cdar fmt)) - l)))) - (values p - (reduce + 0 (map string-length p))))) - ((d) - (values (take m count) - count)) - (else - (values (reverse (unpack (make-list count (cdar fmt)) - l)) - (* count (cdar fmt))))) - (loop (cdr fmt) - (drop m octets) - (cons p acc))))) - - (else - (error (format "Unknown format element: ~a" (car fmt)))))))) - - -;; -;; Packet assembly and disassembly -;; - -(define (make-packet type . args) - (let* ((spec (cdr (assoc type message-specs))) - (msgnum (car spec)) - (fmt (cadr spec)) - (p (pack fmt args))) - (append (uint->u8-list 4 (+ 5 (length p))) - (list msgnum) - p))) - -(define (write-packet ixp type . args) - ((ixp-write ixp) (apply make-packet (cons type args)))) - -(define (read-uint width ixp) - (u8-list->uint ((ixp-read ixp) width))) - -(define (read-packet ixp) - (let* ((len (read-uint 4 ixp)) - (msgnum (read-uint 1 ixp)) - (spec (spec-by-num msgnum)) - (fmt (caddr spec)) - (datum ((ixp-read ixp) (- len 5)))) - (cons (car spec) - (unpack fmt datum)))) - - -;; -;; 9p record -;; -;; This is how I deal with the fact that no two scheme implementations -;; have the same socket API. There are no SRFIs for sockets so that's -;; not likely to change in the near future. -;; -;; You create one of these with (make-ixp read-u8-list write-u8-list). -;; read-u8-list should one argument, count, and return a list of length -;; count of octets (u8s) read from the socket. write-u8-list takes one -;; argument, l (a u8-list), and writes that to the socket. -;; -(define-record-type ixp - (make-ixp read-u8-list write-u8-list) - ixp? - (read-u8-list ixp-read) - (write-u8-list ixp-write)) - - -(define (ixp-transaction ixp type . args) - (apply write-packet (append (list ixp type 1) args)) - (let ((ret (read-packet ixp))) - (if (equal? (car ret) 'RError) - (error (format "IXP Recieve: ~a" ret)) - ret))) - -;; Rewriting this procedure should be all you need to do in order to -;; port this code. -(define (gauche-with-ixp socket proc) - (call-with-client-socket socket - (lambda (in out) - (let ((ixp (make-ixp - (lambda (count) - (let ((vec (make-u8vector count))) - (if (not (equal? (read-block! vec in) count)) - (error "read-octets: short read") - (u8vector->list vec)))) - (lambda (u8-list) - (write-block (list->u8vector u8-list) out) - (flush out))))) - (proc ixp))))) - - -(define (main args) - (gauche-with-ixp (make-client-socket 'unix "/tmp/ns.neale.:0/wmii") - (lambda (ixp) - (let ((root-fid #xf00fb1ba) - (fid 1) - (username "the dink") - (filename "event") - (data "hello\n")) - (ixp-transaction ixp 'TVersion 4096 "9P2000") - (ixp-transaction ixp 'TAttach root-fid #xffffffff username "") - - (ixp-transaction ixp 'TWalk root-fid fid (list filename)) - (ixp-transaction ixp 'TOpen fid 1) - (ixp-transaction ixp 'TWrite fid 0 (list data)) - (ixp-transaction ixp 'TClunk fid) - - (ixp-transaction ixp 'TWalk root-fid fid (list filename)) - (ixp-transaction ixp 'TOpen fid 0) - (write - (let ((cl (caddr (ixp-transaction ixp 'TRead fid 0 4096)))) - (ixp-transaction ixp 'TClunk fid) - (u8-list->string cl))) - (newline)))) - 0) \ No newline at end of file diff --git a/src/misc/deliver.sh b/src/misc/deliver.sh deleted file mode 100755 index 2d20203..0000000 --- a/src/misc/deliver.sh +++ /dev/null @@ -1,38 +0,0 @@ -#! /bin/sh -x - -JUNK=$HOME/Maildir/.Junk - -deliver () { - fn=`date +%s`.$$.`hostname` - mv $1 $2/tmp/$fn - mv $2/tmp/$fn $2/new/ - chmod 600 $2/new/$fn -} - -if [ -d $JUNK ]; then - tmp=`tempfile` - trap "rm -f $tmp" 0 - - bogofilter -p -u > $tmp - case $? in - 0) # spam - deliver $tmp $JUNK - ;; - 1) # ham - /usr/lib/dovecot/deliver < $tmp - ;; - 2) # unsure - for d in .maybe -maybe; do - if [ -d $JUNK$d ]; then - deliver $tmp $JUNK$d - exit 0 - fi - done - - # Fall-through - /usr/lib/dovecot/deliver < $tmp - ;; - esac -else - exec /usr/lib/dovecot/deliver -fi \ No newline at end of file diff --git a/src/misc/dwm-config.h b/src/misc/dwm-config.h deleted file mode 100644 index 4fc2485..0000000 --- a/src/misc/dwm-config.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Description: Neale's DWM config - * Author: Neale Pickett - * Time-stamp: <2008-03-31 11:52:28 neale> - */ - -#define TERM "rxvt" - -/* appearance */ -#define BORDERPX 2 -#define FONT "-adobe-helvetica-medium-r-*-*-10-*-*-*-*-*-*-*" -#define NORMBORDERCOLOR "#cfdde6" -#define SELBORDERCOLOR "#80d0ff" -#define NORMBGCOLOR "#69668b" -#define NORMFGCOLOR "#d3d1e6" -#define SELBGCOLOR "#ccb48f" -#define SELFGCOLOR "#000000" - -/* tagging */ -const char tags[][MAXTAGLEN] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; - -Rule rules[] = { - /* class:instance:title substr tags ref isfloating */ - { "Gimp", tags[5], True }, - { "KNetworkManager", tags[8], False }, -}; - -/* layout(s) */ -#define RESIZEHINTS True /* False - respect size hints in tiled resizals */ -#define SNAP 32 /* snap pixel */ - -Layout layouts[] = { - /* symbol function isfloating */ - { "[]=", tilev, False }, /* first entry is default */ - { "><>", floating, True }, - { "[M]", monocle, False }, -}; - -const char *layoutcycle[] = {"[]=", "[M]"}; - -void -nextlayout(const char *arg) -{ - static int which = 0; - - which = (which + 1) % LENGTH(layoutcycle); - setlayout(layoutcycle[which]); -} - -void -restart(const char *arg) -{ - if (arg) { - execlp(arg, arg, NULL); - } else { - execlp("dwm", "dwm", NULL); - } -} - -/* key definitions */ -#define MODKEY Mod4Mask -Key keys[] = { - /* modifier key function argument */ - { MODKEY, XK_a, spawn, - "exec dmenu_run -fn '"FONT"' -nb '"NORMBGCOLOR"' -nf '"NORMFGCOLOR"' -sb '"SELBGCOLOR"' -sf '"SELFGCOLOR"'" }, - { MODKEY|ShiftMask, XK_Return, spawn, "exec " TERM }, - { MODKEY, XK_l, spawn, "exec screenlock" }, - { MODKEY, XK_m, spawn, "exec " TERM " -e ncmpc" }, - { MODKEY, XK_w, spawn, "exec mpc prev" }, - { MODKEY, XK_v, spawn, "exec mpc toggle" }, - { MODKEY, XK_z, spawn, "exec mpc next" }, - - { MODKEY, XK_n, focusnext, NULL }, - { MODKEY, XK_t, focusprev, NULL }, - { MODKEY, XK_Return, zoom, NULL }, - { MODKEY, XK_equal, nextlayout, NULL }, - { MODKEY|ShiftMask, XK_equal, setlayout, "><>" }, - { MODKEY|ShiftMask, XK_space, togglefloating, NULL }, - { MODKEY, XK_grave, killclient, NULL }, - { MODKEY, XK_0, view, NULL }, - { MODKEY, XK_1, view, tags[0] }, - { MODKEY, XK_2, view, tags[1] }, - { MODKEY, XK_3, view, tags[2] }, - { MODKEY, XK_4, view, tags[3] }, - { MODKEY, XK_5, view, tags[4] }, - { MODKEY, XK_6, view, tags[5] }, - { MODKEY, XK_7, view, tags[6] }, - { MODKEY, XK_8, view, tags[7] }, - { MODKEY, XK_9, view, tags[8] }, - { MODKEY|ShiftMask, XK_0, tag, NULL }, - { MODKEY|ShiftMask, XK_1, tag, tags[0] }, - { MODKEY|ShiftMask, XK_2, tag, tags[1] }, - { MODKEY|ShiftMask, XK_3, tag, tags[2] }, - { MODKEY|ShiftMask, XK_4, tag, tags[3] }, - { MODKEY|ShiftMask, XK_5, tag, tags[4] }, - { MODKEY|ShiftMask, XK_6, tag, tags[5] }, - { MODKEY|ShiftMask, XK_7, tag, tags[6] }, - { MODKEY|ShiftMask, XK_8, tag, tags[7] }, - { MODKEY|ShiftMask, XK_9, tag, tags[8] }, - { MODKEY, XK_q, restart, NULL }, - { MODKEY|ShiftMask, XK_q, quit, NULL }, -}; diff --git a/src/misc/frobnitz.ml b/src/misc/frobnitz.ml deleted file mode 100644 index cd73b16..0000000 --- a/src/misc/frobnitz.ml +++ /dev/null @@ -1,389 +0,0 @@ -(** A stupid adventure game - - Nick wanted an adventure game framework. Here ya go, Nick. - - Compile this with - ocamlc -o foo foo.ml - - @author Neale Pickett - -*) - -(** Directions *) -type direction = North | South | East | West | Up | Down | Emad - -(** An item *) -type item = { - names: string list; - i_full_name: string; - i_description: string; - actions: (string * (item -> unit)) list; -} - -(** A room. Contents are mutable so that the player can pick stuff - up. Exits are mutable so that I can link them back and forth *) -type room = { - r_full_name: string; - r_description: string; - mutable contents: item list; - mutable exits: (direction * room) list; -} - -(** The player *) -type player = { - mutable carrying: item list; - mutable location: room; -} - -let player = { - carrying = []; - location = { - r_full_name = "Nowhere"; - r_description = "Non-descript"; - contents = []; - exits = [] - } -} - -(* - * - * General functions - * - *) - -(** Relocate something - - Note that this does no checks to make sure the item is actually in - src! - - @param i item to relocate - @param src where it comes from - @param dst where it goes - @return (new src, new dst) -*) -let move i src dst = - (List.filter ((!=) i) src, - i :: dst) - - -(** Is the player carrying an item? *) -let carrying p i = - List.exists ((==) i) p.carrying - -(** Drop something *) -let drop i = - if carrying player i then - let carrying, contents = move i player.carrying player.location.contents in - player.carrying <- carrying; - player.location.contents <- contents; - else - raise (Failure ("You're not carrying " ^ i.i_full_name ^ "!")) - - -(** Pick something up *) -let get i = - if carrying player i then - raise (Failure ("You already have " ^ i.i_full_name ^ "!")) - else if List.exists ((==) i) player.location.contents then - let contents, carrying = move i player.location.contents player.carrying in - player.carrying <- carrying; - player.location.contents <- contents; - else - raise (Failure ("You don't see " ^ i.i_full_name ^ " here!")) - - -(** Describe an item *) -let describe i = - print_endline i.i_description - -(* - * - * Rooms - * - * There's really no need to clutter up the global namespace here, - * since all I really need is "start_location" to set the starting - * location. - * - *) -let start_location = - let bigroom = { (* Big room *) - r_full_name = "The big room"; - r_description = "This is that big room just outside the computer lab " ^ - "with the blue ceiling. It smells fresh, yet dirty at the same time. " ^ - "Off to the north is a grassy knoll."; - contents = [ - { (* lantern *) - names = ["brass lantern"; "brass"; "lantern"; "lamp"; "light"]; - i_full_name = "a brass lantern"; - i_description = "This rusty lantern looks like it's been used in " ^ - "one too many adventure games."; - actions = [ - ("rub", - fun self -> - print_endline "Nothing happens."; - ); - ("kick", - fun self -> - print_endline "There'll be a hot time in the old town tonight!"; - ) - ] - }; - { (* stone *) - names = ["smooth"; "stone"; "rock"]; - i_full_name = "a smooth stone"; - i_description = "This stone is smooth. Yes it is."; - actions = [ - ("rub", - fun self -> - print_endline "Your worries seem to vanish."; - ); - ("throw", - fun self -> - print_endline "You throw the stone."; - let carrying, contents = (move self player.carrying - player.location.contents) in - drop self; - print_endline "It lands a stone's throw away."; - ) - ] - } - ]; - exits = [] - } - in - let knoll = { (* Grassy knoll *) - r_full_name = "Grassy knoll"; - r_description = "You find yourself standing on the top of a " ^ - "small mound. The green carpeting of grass beneath your feet " ^ - "beckons kite-flying or frisbee-throwing. Near the bottom of the " ^ - "mound is a funny-looking man intensely examining a teacup. He " ^ - "is wearing a nametag reading \"Emad\"."; - contents = []; - exits = [] - } - in - let emad = { - r_full_name = "Emad"; (* Emad *) - r_description = "You are in Emad. How unpleasant."; - contents = [ - { (* ham sandwich *) - names = ["ham and bacon sandwich"; "bacon sandwich"; "ham sandwich"; - "sandwich"; "ham"; "bacon"]; - i_full_name = "a delicious ham and bacon sandwich"; - i_description = "Named after John Montagu, fourth Earl of Sandwich, " ^ - "this savory instance is comprised of ham and bacon, \"sandwiched\" " ^ - "as it were between two slices of whole-wheat bread."; - actions = [ - ("eat", - fun self -> - print_endline "A little acidic, but not bad." - ) - ] - } - ]; - exits = [] - } - in - begin - bigroom.exits <- [(North, knoll)]; - knoll.exits <- [(South, bigroom); - (Emad, emad)]; - emad.exits <- [(Up, knoll)]; - bigroom - end - -let describe_room r = - let rec display_items = function - | [] -> - " nothing" - | [i] -> (* just one *) - (" " ^ i.i_full_name) - | [i; j] -> (* two *) - (" " ^ i.i_full_name ^ - ", and " ^ j.i_full_name) - | i :: j :: tl -> (* multiple *) - (" " ^ i.i_full_name ^ "," ^ - display_items (j :: tl)) - in - print_endline ""; - print_endline r.r_full_name; - print_endline ""; - print_endline r.r_description; - if (r.contents = []) then - print_endline "" - else - print_endline ("You see" ^ (display_items r.contents) ^ " here.") - - -(* - * - * Player functions - * - *) - - -let rec find_item name l = - match (name, l) with - | _, [] -> - raise Not_found - | name, i :: tl -> - if List.exists ((=) name) i.names then - i - else - find_item name tl - -let rec find_action action l = - match (action, l) with - | _, [] -> - raise Not_found - | action, (name, func) :: tl -> - if (action = name) then - func - else - find_action action tl - -(** Apply action to name - - @param action What to do - @param name What to do it to -*) -let apply_action action name = - match action with - | "describe" | "look" | "l" -> - let i = try - find_item name player.carrying - with Not_found -> - try - find_item name player.location.contents - with Not_found -> - raise (Failure "You're not carrying that.") - in - describe i - | "take" | "get" -> - let i = try - find_item name player.location.contents - with Not_found -> - raise (Failure "You don't see that here.") - in - get i; - print_endline "Taken." - | "drop" -> - let i = try - find_item name player.carrying - with Not_found -> - raise (Failure "You're not carrying that.") - in - drop i; - print_endline "Dropped." - | _ -> - let i = try - find_item name player.carrying - with Not_found -> - raise (Failure "You don't have that.") - in - let a = try - find_action action i.actions - with Not_found -> - raise (Failure ("You can't do that to " ^ i.i_full_name ^ ".")) - in - a i - -(** Move the player - - @param dir direction -*) -let go dir = - let moveout (d, room) = - if d = dir then - begin - player.location <- room; - describe_room player.location; - end - in - let here = player.location in - List.iter moveout player.location.exits; - if here == player.location then - raise (Failure "You can't get there from here.") - -(** Display inventory -*) -let inventory () = - let print_item i = - print_endline ("* " ^ i.i_full_name) - in - if (player.carrying = []) then - print_endline "You are empty-handed." - else - begin - print_endline "You are carrying: "; - List.iter print_item player.carrying - end - - -(** Do something - - @param action What to do -*) -let do_action action = - match action with - | "inventory" | "inv" | "i" -> - inventory () - | "look" | "l" -> - describe_room player.location - | "north" | "n" -> - go North - | "south" | "s" -> - go South - | "east" | "e" -> - go East - | "west" | "w" -> - go West - | "up" | "u" -> - go Up - | "down" | "d" -> - go Down - | "emad" -> - go Emad - | _ -> - print_endline "I'm sorry, Dave, I'm afraid I can't do that." - -(** Parse a line - - @param str the line to parse -*) -let parse str = - try - let action, name = - let pos = String.index str ' ' in - (String.sub str 0 pos, - String.sub str (pos + 1) ((String.length str) - pos - 1)) - in - apply_action action name - with Not_found -> - do_action str - -(** Read-Eval-Print loop -*) -let rec repl () = - let line = read_line () in - print_endline ""; - begin - try - parse (String.lowercase line) - with Failure str -> - print_endline str - end; - repl () - -let main () = - player.location <- start_location; - describe_room player.location; - repl () - -let _ = - try - main () - with End_of_file -> - () - - diff --git a/src/misc/gourmet.sh b/src/misc/gourmet.sh deleted file mode 100755 index 9c506ac..0000000 --- a/src/misc/gourmet.sh +++ /dev/null @@ -1,38 +0,0 @@ -#! /bin/sh - -frm="$1" -ext="$2" -base="${HOME}/.gourmet" - -num="`echo $ext | sed -n 's/^\([0-9]*\)-.*/\1/p'`" - -if [ -z "$num" ]; then - # No number; not a gourmet address - exec cat -fi - -if ! [ -d "$base" ]; then - mkdir "$base" -fi - -if [ -f "$base/$ext" ]; then - num="`cat $base/$ext`" -fi - -left=`expr "$num" - 1` -echo $left > "$base/$ext" - -if [ "$num" -gt 0 ]; then - exec awk " -{ - if (! p && /^Subject: /) { - sub(\"^Subject: \", \"Subject: <$ext: $left left> \"); - p = 1; - } - print; -}" -fi - -# Must have sent too many, return permanent failure code -echo "Address has self-destructed." 1>&2 -exit 69 diff --git a/src/misc/index.head.md b/src/misc/index.head.md deleted file mode 100644 index d391d97..0000000 --- a/src/misc/index.head.md +++ /dev/null @@ -1,2 +0,0 @@ -Title: Miscellaneous hacks - diff --git a/src/misc/lcdutils-0.2-neale.tar.gz b/src/misc/lcdutils-0.2-neale.tar.gz deleted file mode 100644 index 4bd19fb..0000000 Binary files a/src/misc/lcdutils-0.2-neale.tar.gz and /dev/null differ diff --git a/src/misc/mail-expire.sh b/src/misc/mail-expire.sh deleted file mode 100755 index daf8918..0000000 --- a/src/misc/mail-expire.sh +++ /dev/null @@ -1,86 +0,0 @@ -#!/usr/bin/python - -description = '''All Maildir++ folders are checked for old mail. Any messages older than -DAYS days than the newest message in a folder are removed. If there is -a file named"expire" in a maildir, its contents will be used instead of -DAYS for that folder. You can put "12345678" in the "expire" file to -set an expiration of 1413 years, which is probably longer than you will -care about the mail folder. - -Specify a path in MAILDIR to check a specific Maildir. Subfolders will -not be checked in this case. - -''' - -import glob -import os -import sys -import optparse - -progname = sys.argv[0] -debug = 0 - -def expire(dirname, days): - expire = "%s/expire" % dirname - if os.path.exists(expire): - days = int(open(expire).read()) - secs = long(days) * 24 * 60 * 60 - messages = glob.glob("%s/cur/*" % dirname) - messages += glob.glob("%s/new/*" % dirname) - if not messages: - return - messages = [(os.path.getmtime(m), m) for m in messages] - messages.sort() - latest = messages[-1][0] - for m in messages: - if (m[0] + secs) < latest: - try: - _, flags = m[1].split(',') - except ValueError: - continue - if 'S' in flags: - # Only if the mail's been seen - if debug: - print m[1] - else: - os.remove(m[1]) - -def usage(err=None): - if err: - print "Error: %s" % err - print - print __doc__ % globals() - if err: - sys.exit(1) - else: - sys.exit() - -def main(): - import optparse - global debug - - parser = optparse.OptionParser(usage='usage: %prog [options] [MAILDIR ...]', - description=description) - parser.add_option('-d', '--debug', dest='debug', action='store_true', - help="run in debug mode (don't do anything)") - parser.add_option('-t', '--time', dest='days', metavar='DAYS', type='int', - default=90, - help="Mail older than DAYS days will be removed (default 90)") - options, args = parser.parse_args() - - debug = options.debug - - if (len(args) == 0): - base = os.path.expanduser("~/Maildir") - files = [os.path.join(base, x) for x in os.listdir(base) if x[0] == '.'] - dirs = [f for f in files if os.path.isdir(f)] - dirs.append(base) - else: - dirs = args - - for d in dirs: - expire(d, options.days) - - -if __name__ == "__main__": - main() diff --git a/src/misc/spamfairy.py b/src/misc/spamfairy.py deleted file mode 100755 index 7ab012e..0000000 --- a/src/misc/spamfairy.py +++ /dev/null @@ -1,190 +0,0 @@ -#! /usr/bin/python - -import os -import glob -import time -from sets import Set - -bogosity = {'U': "Unsure", - 'S': "Spam", - 'H': "Ham"} - -def classification(filename): - f = file(filename) - for l in f: - if l.startswith('X-Bogosity: '): - return l[12] - elif not l.strip(): - return None - -def reclassify(oldtype, newtype, filenames): - cmd = 'bogofilter -b -v' - t = oldtype + newtype - if t == 'SH': - cmd += ' -Sn' - elif t == 'HS': - cmd += ' -Ns' - elif t == 'UH': - cmd += ' -n' - elif t == 'US': - cmd += ' -s' - else: - raise ValueError('Unable to reclassify %s' % t) - - cmd += ' 2>/dev/null' - - # Reclassify them - f = os.popen(cmd, 'w') - for fn in filenames: - f.write('%s\n' % fn) - ret = f.close() - if ret: - raise IOError("bogofilter puked on %s (%r)" % (fn, ret)) - - # Add new bogosity header - for fn in filenames: - base, filename = os.path.split(fn) - folder, _ = os.path.split(base) - tmpfn = os.path.join(folder, 'tmp', filename) - - inf = file(fn) - outf = file(tmpfn, 'w') - - headered = False - for l in inf: - if l.startswith('X-Bogosity: '): - l = (('X-Bogosity: %s (Reclassified), was ' % bogosity[newtype]) - + l[12:]) - headered = True - elif not l.strip() and not headered: - l = (('X-Bogosity: %s (Reclassified)\n' % bogosity[newtype])) - headered = True - outf.write(l) - os.rename(tmpfn, fn) - -def visit(path, folder_type): - # Read in list of already-processed files - visited = os.path.join(path, 'spamfairy-visited') - oldfiles = Set() - try: - f = file(visited) - for l in f: - oldfiles.add(l.strip()) - f.close() - except IOError: - pass - - if folder_type == 'S': - subdirs = ('cur', 'new') - else: - subdirs = ('cur',) - - for sd in subdirs: - # Read in list of current files in the directory - root = os.path.join(path, sd) - files = Set(os.listdir(root)) - - # We only consider the difference - todo = files - oldfiles - - # Check new messages for reclassification - reclass = {} # {oldtype: [filenames]} - for fn in todo: - fn = os.path.join(root, fn) - c = classification(fn) - if not c: - continue - if c != folder_type: - l = reclass.setdefault(c, []) - l.append(fn) - - # Reclassify anything that needs it - for c, filenames in reclass.iteritems(): - try: - reclassify(c, folder_type, filenames) - except ValueError: - pass - - # Write out new list of processed files - new_visited = "%s.%d" % (visited, os.getpid()) - f = file(new_visited, 'w') - for fn in files: - f.write('%s\n' % fn) - f.close() - os.rename(new_visited, visited) - - -def get_folder_type(path): - """Auto-detect type of a maildir. - - You can have the following files in your maildir: - spamfairy-ignore : skip this folder entirely - spamfairy-spam : treat this folder as spam - spamfairy-ham : treat this folder as ham - - Otherwise, check the name of the folder: - Trash : skip - Drafts : skip - Sent : skip - Unsure : skip - Junk.maybe : skip - Junk : spam - - Otherwise, treat it as a ham folder. - - Return values are None for skip, 'S' for spam, 'H' for ham - - """ - - path = os.path.realpath(path) - _, folder = os.path.split(path) - folder = folder.lower() - if os.path.exists(os.path.join(path, 'spamfairy-ignore')): - return None - elif os.path.exists(os.path.join(path, 'spamfairy-ham')): - return 'H' - elif os.path.exists(os.path.join(path, 'spamfairy-spam')): - return 'S' - elif folder in ('.sent', '.drafts', '.trash', '.unsure', '.junk.maybe'): - return None - elif folder in ('.junk', '.spam'): - return 'S' - else: - return 'H' - - -def sprinkle(folders): - """Sprinkle magic spamfairy dust on the given folders""" - - if not folders: - maildir = os.path.expanduser(os.path.join('~', 'Maildir')) - folders = [maildir] - folders += glob.glob(os.path.join(maildir, '.??*')) - - # Only do maildirs - folders = filter(lambda d: os.path.isdir(os.path.join(d, 'cur')), - folders) - - for path in folders: - folder_type = get_folder_type(path) - if not folder_type: - continue - visit(path, folder_type) - -def compact(wordlist): - """Compact bogofilter database""" - otime = os.path.getmtime(wordlist) - now = time.time() - if now - otime > 60*60*24*11: - new = '%s.new' % wordlist - ret = os.system('bogoutil -d %s | bogoutil -l %s' % (wordlist, new)) - if not ret: - os.rename(new, wordlist) - -if __name__ == '__main__': - import sys - - wordlist = os.path.expanduser(os.path.join('~', '.bogofilter', 'wordlist.db')) - if os.path.exists(wordlist): - sprinkle(sys.argv[1:]) - compact(wordlist) diff --git a/src/misc/wbackup.tar.gz b/src/misc/wbackup.tar.gz deleted file mode 100644 index 39d7779..0000000 Binary files a/src/misc/wbackup.tar.gz and /dev/null differ diff --git a/src/misc/zsdump.tar.gz b/src/misc/zsdump.tar.gz deleted file mode 100644 index d25db80..0000000 Binary files a/src/misc/zsdump.tar.gz and /dev/null differ diff --git a/src/postscript/.sconsign b/src/postscript/.sconsign deleted file mode 100644 index d60f426..0000000 --- a/src/postscript/.sconsign +++ /dev/null @@ -1,4 +0,0 @@ -index.html: - 12dab84c3ad5b0dba380c051471c14d6 - - -index.ptml: 1042003175 - 39a0ed00cb554392574b5955dbdc0af9 - -links.html: - 962d7fd4c69ea67cfeb1d0cc88e892a6 - - -links.ptml: 1041913579 - bd8a21beca5f285bf5e8ba50e86f340f - diff --git a/src/postscript/alice.ps b/src/postscript/alice.ps deleted file mode 100644 index e74706a..0000000 --- a/src/postscript/alice.ps +++ /dev/null @@ -1,562 +0,0 @@ -%!PS-Adobe-2.0 -%%Title: Alice in DIGITALand -- an example application of skel.ps -%%Creator: Neale Pickett -%%CreationDate: Thu Nov 22 15:27:53 MST 1998 -%% Time-stamp: <2002-10-22 09:34:24 neale> -%%EndComments - -/FontSize 12 def - -/RegFont /Times-Roman def -/BoldFont /Times-Bold def -/ItalFont /Times-Italic def - -/RegFSet RegFont findfont FontSize scalefont def -/BoldFSet BoldFont findfont FontSize scalefont def -/HeadFSet BoldFont findfont FontSize 1.1 mul scalefont def -/ItalFSet ItalFont findfont FontSize scalefont def - -/SetRegFont { RegFSet setfont } def -/SetBoldFont { BoldFSet setfont } def -/SetHeadFont { HeadFSet setfont } def -/SetItalFont { ItalFSet setfont } def - -/LM 50 def -/BM 50 def -/RM 580 LM sub def -/TM 760 BM sub def - -/indentLevel 30 def - -% Re-set the margins -/reset_margins { - /lm LM def - /rm RM def -} def - -reset_margins - -% Move down just a little -/down { - reset_margins - lm indentation add currentpoint exch pop - FontSize 3 div sub - moveto -} def - -% Move to the next line -/next { - reset_margins - lm indentation add currentpoint exch pop % LM Y - FontSize 1.1 mul sub % LM Y' - moveto - currentpoint exch pop - BM lt { - showpage - LM TM moveto - } {} ifelse -} def - -% Move to the previous line -/prev { - lm indentation add currentpoint exch pop % LM Y - FontSize 1.1 mul add % LM Y' - moveto -} def - -% Re-align the indentation -/align { - lm indentation add currentpoint exch pop moveto -} def - -% Indent once -/indentation 0 def -/indent { - /indentation indentation indentLevel add def - align -} def - -% Deindent -/deindent { - /indentation indentation indentLevel sub def - align -} def - -% Show left justified -/lshow { - gsave - % Set the left margin - dup - stringwidth pop - LM add - /lm exch def - - currentpoint exch pop % (str) Y - LM exch % (str) x Y - moveto show - grestore -} def - -% Show centered -/cshow { - gsave - dup % (str) (str) - stringwidth pop % (str) x - 2 div % (str) x/2 - RM LM sub 2 div % (str) x/2 RM/2 - exch sub LM add % (str) x' - currentpoint exch pop % (str) x' Y - moveto show - grestore -} def - -% Show right justified -/rshow { - gsave - dup % (str) (str) - stringwidth pop % (str) x - - % set the right margin - dup - RM exch sub padwidth sub - /rm exch def - - RM exch sub % (str) x' - currentpoint exch pop % (str) x' Y - moveto show - grestore -} def - -% Show in a bold font -/bshow { - SetBoldFont - show - SetRegFont -} def - -% Show in a italics font -/ishow { - SetItalFont - show - SetRegFont -} def - -% I totally stole this out of the blue book. -/wordbreak ( ) def -/BreakIntoLines { - /proc exch def - /linelength exch def - /textstring exch def - /curwidth exch def - - /breakwidth wordbreak stringwidth pop def - /lastwordbreak 0 def - - /startchar 0 def - /restoftext textstring def - - { - restoftext wordbreak search - - { - /done false def - } { - () exch - wordbreak exch - /done true def - } ifelse - - /nextword exch def pop - /restoftext exch def - /wordwidth nextword stringwidth pop def - - curwidth wordwidth add linelength gt - { - textstring startchar - lastwordbreak startchar sub - getinterval proc - /startchar lastwordbreak def - /curwidth wordwidth breakwidth add def - } { - /curwidth curwidth wordwidth add - breakwidth add def - } ifelse - - /lastwordbreak lastwordbreak - nextword length add 1 add def - - done { - exit - } { - } ifelse - } loop - /lastchar textstring length def - textstring startchar lastchar startchar sub - getinterval proc -} def - -% Show some text, and word-wrap it if necessary, then move to the next line -/wshow { - 0 exch - /x currentpoint pop def - rm x sub % Line length - { - show next - x currentpoint exch pop moveto - } - BreakIntoLines -} def - -% Show indented, wrapped text -/iwshow { - indentLevel exch - /x currentpoint pop def - rm x sub - indentLevel 0 rmoveto - { - show next - x currentpoint exch pop moveto - } - BreakIntoLines -} def - -% Show inverse-indented, wrapped text -/iiwshow { - indentLevel neg exch - /x currentpoint pop indentLevel add def - rm x sub - { - show next - x currentpoint exch pop moveto - } - BreakIntoLines - indentLevel neg 0 rmoveto -} def - - -LM TM moveto -SetRegFont - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Content goes here ;-) - -(Alice in DIGITALand) cshow next - -(Author: ) show (rals@pineapple.bbs.com) ishow next next align - -("Where am I?" asked Alice, as she peered at the large 7-lettered sign -with the standard blue letters.) iwshow - -("You're in Digitaland," replied the security guard, "May I see your -badge?") iwshow - -("I don't have a badge.") iwshow - -("Did you lose it?") iwshow - -("No," answered Alice in a puzzled tone. "How could I lose something I -never had?") iwshow - -("If it's not lost then you must show it to me.") iwshow - -("I can't. I don't have one.") iwshow - -("Then you'll have to have a temporary.") iwshow - -("A temporary what?" asked Alice, more confused then ever.) iwshow - -("A temporary Badge. What's your badge number?" requested the guard.) iwshow - -("I don't have one") iwshow - -("Of course not, Ken Olsen has 1. Give me your badge number, and your -cost center") iwshow - -("I'm so confused. I can't do this. I've already said 3 times why. Do -I have to tell you 4?") iwshow - -("Ahhh. 3XY, badge number 4. You must be very important to have such a -low badge number. I should have immediately recognized how low by your -state of extreme confusion. Here's your temporary. Go right on in.") iwshow - -(Alice pasted the sticky paper to her dress and headed down the hall. -Not 10 feet ahead she saw a rather distressed looking rabbit coming -toward her. He was dressed in a pair of torn, faded jeans, and a dirty -tee shirt.) iwshow - -("What's wrong?" Alice asked.) iwshow - -("I'm late! I'm late!" exclaimed the rabbit as he peered at the PERT -chart dangling from his pocket protector.) iwshow - -("Late for what?" asked Alice.) iwshow - -("My date. I'm going to miss my date. I've got a deadline to meet and -I'm not going to make it.") iwshow - -("Well, if it's already dead, it probably won't mind. In fact it isn't -likely to be going too far in such a state. I'm sure that however long -you take will be just fine.") iwshow - -("You obviously don't understand. Everything takes longer than it -really does. It doesn't matter what you are doing, only that you meet -your date, and that's always impossible.") iwshow - -("Well if it's impossible, why would anyone expect you to meet it?" -Almost at once regretting that she had asked. Was this was going to be -as confusing as badges?) iwshow - -("It's really very simple. In order to move forward, you need a goal. -Any goal will do. It just has to be impossible to do. To motivate the -troops, you have to make goals very challenging. It's really only -there to get a stake in the ground, you know. After that we march in -step until we reach our objective. The date really doesn't mean -anything. You simple have to understand that we are going to do the -right thing.") iwshow - -("But the if the goal is impossible, and really doesn't mean anything -why are you trying to go there. Wouldn't it be simpler to first figure -out what you are really going to do, then figure out how to get there?") -iwshow - -("You obviously don't understand the process. And as I said before I'm -late so there is obviously only one thing to do.") iwshow - -("Hurry up and rush off?" Alice asked, hoping it would sound more like -a suggestion than a question.) iwshow - -("No. No. No. A meeting. Let me find the Mad Manager and a number of -involved, interested, or warm bodies.") iwshow - -("That will obviously take a lot of time. I don't think you have any to -waste.) iwshow - -("No it won't. All we have to do is find a conference room. There are -lots of them right over here.") iwshow - -("But," started Alice, "those rooms are all full of people. Don't we -need an empty conference room?") iwshow - -("Silly thought. If we want to find the Mad Manager and some meeting -attendees, why would we look in an empty conference room? Anyway, it's -impossible to ever find an empty conference room.") iwshow - -(The rabbit took Alice by the hand, and promptly lead her into the -largest, fullest conference room. Alice immediately noticed that the -wastebasket was quite full of foam cups, and overhead projector bulbs. -These people had obviously been here for a long time.) iwshow - -(At the head of the table sat a man with a rather funny suit wearing a -large hat.) iwshow - -("Why" whispered Alice to the rabbit, "is that man wearing that funny -hat? Who is he?") iwshow - -("I'm the Mad Manager," answered the man at the end of the table, -obviously overhearing the question, " And I'll be happy to tell you -why I'm wearing this Hat, but that topic is not on the agenda.") iwshow - -("Why don't we change the agenda?" asked a person in the corner.) iwshow - -("Is that a topic for another meeting?" replied the manager.) iwshow - -("Is what a topic for another meeting?" voiced a third. "The reason -for the hat, or why we don't change the agenda?") iwshow - -("Why don't we take this off line?" queried another.) iwshow - -("Does everyone agree that these are all topics we should address?" -asked the mad manager.) iwshow - -("Possibly so. " injected the person in the corner. "Could it be that -we have a hidden agenda?") iwshow - -("Oh no!" the Mad Manager began, the dismay obvious on his face, -"someone has hidden the agenda again! Let me put on my process hat and -we'll see if we can work this issue.") iwshow - -(With that, he removed his rather amusing top hat, and place a big green -fedora on his head.) iwshow - -("Now, with my process hat on, I'd like to address the issue of the -hidden agenda. Since we can't have a productive meeting without an -agenda, it is up to all of us to find it.") iwshow - -("But, " a voice from the corner piped in, "who is going to drive this -issue?") iwshow - -("Do we have an action item here?" asked another attendee.) iwshow - -("Does anyone here want to work this?" asked the mad manager.) iwshow - -("Who originally brought this up?" asked another.) iwshow - -("I believe that the woman who came in with the rabbit proposed this. -Shouldn't she own it?") iwshow - -("Well" the Manager stated, pointing to Alice. "I'd say that this is -your issue.") iwshow - -("What issue. I don't have any issues. " retorted Alice, nervously -fingering her temporary badge. "I only posed a simple question.") iwshow - -("I'm not sure we can accept that," the manager declared. "We need a -date.") iwshow - -("But, " Alice began, remembering what the rabbit told her about dates, -"a date is impossible.") iwshow - -(From the back of the room another voice asked, "How about a date for a -date?") iwshow - -("The least we can ask it that you give us a date when you will be able -to give us the date for the date." stated the person in the corner.) -iwshow - -("I'm not sure I can do that," Alice opened, "since I don't know what -I'm supposed to give you a date for. I'm having a problem trying to -figure out what you want me to do.") iwshow - -("We don't have any problems here, only opportunities!" Piped a chorus -of voices.) iwshow - -("It's really quite obvious," the mad manager declared as he reached -behind him for a striped blue and gray beret, "let me put on my Digital -hat for a moment," he continued doffing the fedora and flipping on his -latest selection, "You must do the right thing.") iwshow - -("Yes. yes. " chimed the chorus of attendees, "Do the right thing.) -iwshow - -("Now, who is keeping the minutes?" the manager asked as he pitched the -beret and placed the fedora back on his head. "We need to record this -action item so we can come back to it later.") iwshow - -("We obviously can't deal with this issue until we can determine whose -meeting this is?") iwshow - -("Should we schedule some time to cover that topic?" asked one of the -attendees.) iwshow - -("Whose going to drive this?" asked another.) iwshow - -(Just at the Mad Manager was pulling out a rather worn pith helmet, a -voice in the back suggested "Let's take a break and work some of this -1x1 off line") iwshow - -(Being closest to the door Alice was the first to leave. She quickly -dashed down the hall, and ran up the first flight of stairs she -encountered, relieved to be free of the madness.) iwshow - -(When she opened the door the scene that confronted her made her wonder -if returning to the meeting wasn't a bad idea. Seated around a large -oval table were what appeared to be playing cards, each dressed in a -gray or navy blue three piece suit. Around each neck was a rather -oddly shaped handle \(or were they nooses?\) made of silk, or polyester.) -iwshow - -("Off with her head!" screamed the queen of hearts who was sitting at -the head of the table. Alice noticed that her tie was silk, and each -card seated near her was dressed in a suit and noose combination -similar to the queen's.) iwshow - -("Why would you want to remove my head?" Alice asked. By now she was -feeling beyond confused.) iwshow - -("It's not a modern, iconic, user friendly, menu driven, color, PC -compatible user interface," replied the queen, in a tone that would -need to come up two notches to be vaguely considered condescending.) -iwshow - -("It happens to suit me just fine," retorted Alice.) iwshow - -("What are you an engineer or something?" asked the 7 of spades.) iwshow - -("No, I'm Alice. Who are you?") iwshow - -("Marketing." they replied in perfect fifty-two part harmony.) iwshow - -("And what is that?" asked Alice.) iwshow - -(There was a brief interlude of silence as each of the cards fidgeted -with their ties, checked their watches and scribbled notes on the pads -of paper contained in a handsome genuine imitation leather folder -embossed with the company logo. Then one by one, as dominoes would do, -they turned to the person on the left until they all stared at the -queen of hearts.) iwshow - -(The queen cleared her throat, adjusted her tie a second time and stared -directly at Alice. "We provide the strategic thinking necessary to -grow the business.") iwshow - -("Oh," said Alice, "you figure out what products to build!") iwshow - -("Heavens, no!" exclaimed the Queen, "That's too tactical. We feel -it's our job to develop the vision for the long term.") iwshow - -("You develop things," began Alice, "so you build the products?") iwshow - -(In unison each member of the table made a face reminiscent of the look -a small child gets upon tasting spoiled dead roaches for the first -time.) iwshow - -("Uggggh, that's even more tactical," jeered the chorus.) iwshow - -("No! No!" shouted the Queen. "You still do not understand. We take -the pulse of the key market leaders demand curve.") iwshow - -("I see now." said Alice, "You sell the products.") iwshow - -(By now the chorus of cards chanting "Tac-ti-cal! Tac-ti-cal!" was -becoming too much.) iwshow - -(The queen was furious and repeated her original greeting. "Off with -her head! Off With her head") iwshow - -("WAIT!" demanded Alice. "I believe I understand. You are all -responsible for driving the solution opportunities for the key client -supply perceptions through strategic vision management!") iwshow - -(Alice wondered if she should add something about the claws catching, -and frumious bandersnatches and thought that she'd best leave it at -that before she became ill.) iwshow - -("Yes," screamed the cards, "That's exactly right!") iwshow - -("And how, might I ask, do you accomplish these lofty and important -goals?") iwshow - -("By calling a BOD," the queen responded.) iwshow - -("And what, pray tell, might that be?" inquired Alice as she looked for -the quickest escape route, hoping that this jabber would keep her head -attached long enough to get out.) iwshow - -("A Board of Directors," began the queen, just as Alice noticed the door -to the left of the table. "It's a type of high level meeting.") iwshow - -("A meeting????!!!!" exclaimed Alice. "Not another meeting!" With -that she bolted for the door, no longer fearing for her head. Her only -hope was that she make it through before the agenda hit the overhead. -In a dead run, she passed through the door just as the projector lamp -flicked on. The sound of the fan was the last sound to fade as the -door closed.) iwshow - -(Breathlessly she looked up to see a large open area. Directly in front -of her was an enclosed area lined on one side with triple chrome table. -A stack of plastic trays was at the foyer.) iwshow - -(As she wandered through an assortment of sandwiches, prepared foods, -soft drinks and salad began their daily spiel. "Eat Me! Drink Me! Eat -Me!") iwshow - -("Oh no," answered Alice, "I may know nothing about dates, and problems -and meetings and agendas, and marketing and badges, but I do know food. -I'm not gonna touch any of you. After the morning I've had I deserve a -nice cheese steak \(no lettuce\)!") iwshow - -(With that, Alice opened the nearest exit door and left. A resounding -high pitched whine sang its midday good-byes as Alice returned to the -real world.) iwshow - -showpage diff --git a/src/postscript/banner.ps b/src/postscript/banner.ps deleted file mode 100644 index fb987fd..0000000 --- a/src/postscript/banner.ps +++ /dev/null @@ -1,111 +0,0 @@ -%!PS-Adobe-2.0 -%%Description: Boilerplate for multi-page banners - -% --- Leave this alone, go to the bottom to start writing stuff --- - -% Define margins -/LM 50 def -/BM 50 def -/RM 580 LM sub def -/TM 760 BM sub def - -% font types -/times { - /font /Times-Roman def -} def - -/courier { - /font /Courier def -} def - -% font sizes -/monstrous { - /FontSize 312 def - /font findfont FontSize scalefont setfont -} def - -/huge { - /FontSize 288 def - font findfont FontSize scalefont setfont -} def - -/jumbo { - /FontSize 188 def - font findfont FontSize scalefont setfont -} def - -/large { - /FontSize 122 def - font findfont FontSize scalefont setfont -} def - - -% Line kerning -/smooshed { - /Spacing .5 def -} def - -/even { - /Spacing .75 def -} def - -/wide { - /Spacing 1 def -} def - -% Show text in landscape -/lshow { - gsave - 90 rotate - show - grestore -} def - -% start on line 1 -/offset 0 def - -% Form feed -/ff { - showpage - /offset 0 def -} def - -% Line feed (in current font) -/lf { - /offset offset Spacing FontSize mul add def -} def - -% Show top text -/disp { - lf - LM offset add RM gt { - ff - lf - } { - } ifelse - LM offset add BM moveto - lshow -} def - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%% Start writing your data here - -% How do you want it to appear? -courier jumbo wide - -% Even bigger font: times, letters closely spaced -%times huge smooshed - -% Smaller times, normal spacing -%times large even - -% Monstrous, the biggest of all -%times monstrous smooshed - -(This) disp -(is some) disp -(really) disp -(large) disp -(text.) disp -ff diff --git a/src/postscript/emergency-card.png b/src/postscript/emergency-card.png deleted file mode 100644 index 070247b..0000000 Binary files a/src/postscript/emergency-card.png and /dev/null differ diff --git a/src/postscript/emergency-card.ps b/src/postscript/emergency-card.ps deleted file mode 100644 index 3e45e18..0000000 --- a/src/postscript/emergency-card.ps +++ /dev/null @@ -1,357 +0,0 @@ -%!PS-Adobe-2.0 -%%Creator: Neale Pickett -%%Title: Emergency card -%%Pages: 2 -%%PageOrder: Ascend -%%BoundingBox: 50 50 358 294 -%%EndComments - -% A credit card is 0 0 154 244, this page is twice that so you can fold -% it in half. Store phone numbers inside or whatever. - -/RegFont /Times-Roman findfont 8 scalefont def -/BoldFont /Times-Bold findfont 8 scalefont def - -RegFont setfont - -/bshow { - BoldFont setfont - show - RegFont setfont -} def - -/h1 { - /Times-Bold findfont 11 scalefont setfont - show - RegFont setfont -} def - -/nl { - currentpoint exch pop 10 exch 10 sub moveto -} def - -/tab { - currentpoint exch pop moveto -} def - -/hl { - gsave - currentpoint exch pop 10 exch moveto - 0.3 setlinewidth - 134 0 rlineto - closepath stroke - grestore - nl -} def - -/star-of-life { - gsave - translate - 0.13 -0.13 scale - [] 0 setdash -1 setlinewidth -0 setlinejoin -0 setlinecap -currentrgbcolor % push color -gsave [1 0 0 1 0 0] concat -gsave -1 1 1 setrgbcolor -newpath -71.9375 6.84375 moveto -71.9375 51.09375 lineto -33.625 28.96875 lineto -8 73.375 lineto -46.3125 95.46875 lineto -8 117.59375 lineto -33.625 162.03125 lineto -71.9375 139.90625 lineto -71.9375 184.15625 lineto -123.25 184.15625 lineto -123.25 139.9375 lineto -161.53125 162.03125 lineto -187.1875 117.59375 lineto -148.875 95.5 lineto -187.1875 73.375 lineto -161.53125 28.96875 lineto -123.25 51.0625 lineto -123.25 6.84375 lineto -71.9375 6.84375 lineto -closepath -fill -grestore -setrgbcolor currentrgbcolor -[] 0 setdash -1.7 setlinewidth -0 setlinejoin -1 setlinecap -newpath -71.9375 6.84375 moveto -71.9375 51.09375 lineto -33.625 28.96875 lineto -8 73.375 lineto -46.3125 95.46875 lineto -8 117.59375 lineto -33.625 162.03125 lineto -71.9375 139.90625 lineto -71.9375 184.15625 lineto -123.25 184.15625 lineto -123.25 139.9375 lineto -161.53125 162.03125 lineto -187.1875 117.59375 lineto -148.875 95.5 lineto -187.1875 73.375 lineto -161.53125 28.96875 lineto -123.25 51.0625 lineto -123.25 6.84375 lineto -71.9375 6.84375 lineto -closepath -stroke -gsave -setrgbcolor currentrgbcolor -newpath -75.09375 10 moveto -75.09375 56.53125 lineto -34.78125 33.25 lineto -12.28125 72.21875 lineto -52.59375 95.5 lineto -12.28125 118.75 lineto -34.78125 157.71875 lineto -75.09375 134.4375 lineto -75.09375 181 lineto -120.09375 181 lineto -120.09375 134.46875 lineto -160.375 157.71875 lineto -182.875 118.75 lineto -142.5625 95.5 lineto -182.875 72.21875 lineto -160.375 33.25 lineto -120.09375 56.5 lineto -120.09375 10 lineto -75.09375 10 lineto -closepath -fill -grestore -gsave -1 1 1 setrgbcolor -newpath -92.517151 28.749341 moveto -92.408986 25.487473 95.364102 22.444786 98.522226 22.444786 curveto -100.78169 22.444786 103.56391 24.163507 103.49852 27.028713 curveto -102.70837 61.652668 100.60467 131.89502 99.809866 166.84929 curveto -99.785836 167.9063 98.454636 167.43783 98.406332 166.35356 curveto -96.861909 131.68636 93.680464 63.830863 92.517151 28.749341 curveto -closepath -eofill -grestore -setrgbcolor currentrgbcolor -[] 0 setdash -0.60000002 setlinewidth -0 setlinejoin -0 setlinecap -newpath -92.517151 28.749341 moveto -92.408986 25.487473 95.364102 22.444786 98.522226 22.444786 curveto -100.78169 22.444786 103.56391 24.163507 103.49852 27.028713 curveto -102.70837 61.652668 100.60467 131.89502 99.809866 166.84929 curveto -99.785836 167.9063 98.454636 167.43783 98.406332 166.35356 curveto -96.861909 131.68636 93.680464 63.830863 92.517151 28.749341 curveto -closepath -stroke -gsave -1 1 1 setrgbcolor -newpath -94.036939 33.435356 moveto -96.542562 33.435356 97.667652 34.958914 99.217717 36.299367 curveto -100.71504 37.594206 101.88918 38.77889 101.88918 40.05277 curveto -101.88918 41.391534 100.90645 40.990382 99.865157 41.482074 curveto -99.316637 41.74108 99.365585 42.300792 98.469657 42.300792 curveto -96.316099 42.300792 95.45867 40.274406 92.51715 40.274406 curveto -90.093039 40.274406 86.944591 43.179145 86.944591 48.506596 curveto -86.944591 56.552685 90.047493 60.158311 93.720316 62.944591 curveto -94.100263 72.506596 lineto -90.174142 70.860159 80.042216 61.931473 80.042216 49.519789 curveto -80.042216 38.718116 87.055227 33.435356 94.036939 33.435356 curveto -closepath -eofill -grestore -setrgbcolor currentrgbcolor -[] 0 setdash -0.60000002 setlinewidth -0 setlinejoin -0 setlinecap -newpath -94.036939 33.435356 moveto -96.542562 33.435356 97.667652 34.958914 99.217717 36.299367 curveto -100.71504 37.594206 101.88918 38.77889 101.88918 40.05277 curveto -101.88918 41.391534 100.90645 40.990382 99.865157 41.482074 curveto -99.316637 41.74108 99.365585 42.300792 98.469657 42.300792 curveto -96.316099 42.300792 95.45867 40.274406 92.51715 40.274406 curveto -90.093039 40.274406 86.944591 43.179145 86.944591 48.506596 curveto -86.944591 56.552685 90.047493 60.158311 93.720316 62.944591 curveto -94.100263 72.506596 lineto -90.174142 70.860159 80.042216 61.931473 80.042216 49.519789 curveto -80.042216 38.718116 87.055227 33.435356 94.036939 33.435356 curveto -closepath -stroke -gsave -setrgbcolor currentrgbcolor -newpath -94.986808 36.126649 moveto -96.778096 35.842684 96.597917 36.918831 97.39314 37.614775 curveto -95.554706 37.669411 95.147378 36.898305 94.986808 36.126649 curveto -closepath -eofill -grestore -gsave -1 1 1 setrgbcolor -newpath -102.52243 66.934037 moveto -102.26913 76.05277 lineto -102.26913 81.62722 87.514512 91.407424 87.514512 101.38259 curveto -87.514512 109.06464 93.688655 113.98417 95.968338 115.12401 curveto -95.683377 107.08179 lineto -95.683377 107.08179 92.897098 105.20276 92.897098 102.01583 curveto -92.897098 97.506158 109.86807 85.891676 109.86807 77.002639 curveto -109.86807 70.699933 105.56201 68.348285 102.52243 66.934037 curveto -closepath -eofill -grestore -setrgbcolor currentrgbcolor -[] 0 setdash -0.60000002 setlinewidth -0 setlinejoin -0 setlinecap -newpath -102.52243 66.934037 moveto -102.26913 76.05277 lineto -102.26913 81.62722 87.514512 91.407424 87.514512 101.38259 curveto -87.514512 109.06464 93.688655 113.98417 95.968338 115.12401 curveto -95.683377 107.08179 lineto -95.683377 107.08179 92.897098 105.20276 92.897098 102.01583 curveto -92.897098 97.506158 109.86807 85.891676 109.86807 77.002639 curveto -109.86807 70.699933 105.56201 68.348285 102.52243 66.934037 curveto -closepath -stroke -gsave -1 1 1 setrgbcolor -newpath -101.35093 111.54617 moveto -101.35093 111.54617 107.14512 115.37689 107.14512 120.18997 curveto -107.14512 124.30746 103.98764 128.07412 100.25762 131.96931 curveto -95.900204 136.51968 94.980033 142.21601 97.551452 148.17942 curveto -97.773087 153.0554 lineto -95.905013 151.53561 92.960422 146.78869 92.960422 138.87071 curveto -92.960422 129.33988 101.12929 126.47258 101.12929 117.68866 curveto -101.35093 111.54617 lineto -closepath -eofill -grestore -setrgbcolor currentrgbcolor -[] 0 setdash -0.60000002 setlinewidth -0 setlinejoin -0 setlinecap -newpath -101.35093 111.54617 moveto -101.35093 111.54617 107.14512 115.37689 107.14512 120.18997 curveto -107.14512 124.30746 103.98764 128.07412 100.25762 131.96931 curveto -95.900204 136.51968 94.980033 142.21601 97.551452 148.17942 curveto -97.773087 153.0554 lineto -95.905013 151.53561 92.960422 146.78869 92.960422 138.87071 curveto -92.960422 129.33988 101.12929 126.47258 101.12929 117.68866 curveto -101.35093 111.54617 lineto -closepath -stroke -gsave -1 1 1 setrgbcolor -newpath -100.21108 151.25066 moveto -100.21108 151.25066 102.90238 152.69861 102.90238 156.47493 curveto -102.90238 160.02958 98.451601 163.27556 97.773087 163.75726 curveto -97.11579 164.2239 96.863869 163.61619 97.39314 163.12401 curveto -97.939619 162.61583 100.17942 159.61423 100.17942 156.15831 curveto -100.21108 151.25066 lineto -closepath -eofill -grestore -setrgbcolor -[] 0 setdash -0.60000002 setlinewidth -0 setlinejoin -0 setlinecap -newpath -100.21108 151.25066 moveto -100.21108 151.25066 102.90238 152.69861 102.90238 156.47493 curveto -102.90238 160.02958 98.451601 163.27556 97.773087 163.75726 curveto -97.11579 164.2239 96.863869 163.61619 97.39314 163.12401 curveto -97.939619 162.61583 100.17942 159.61423 100.17942 156.15831 curveto -100.21108 151.25066 lineto -closepath -stroke -grestore - - - grestore -} def - -%%Page: 1 - -% Get away from the edge of the paper -50 50 translate - -% Draw some lines for cutting -gsave - 0.9 setgray - - 154 0 moveto - 154 244 lineto - closepath stroke - - 0 0 moveto - 308 0 lineto - 308 244 lineto - 0 244 lineto - closepath stroke -grestore - -125 240 star-of-life - -10 230 moveto -(Name) bshow 50 tab (John Smith) show nl -(Address) bshow 50 tab (21 Jump Street) show nl - 50 tab (New York, NY USA) show nl - -nl -30 tab (Notify In Emergency) h1 hl - -(Name) bshow 50 tab (Sally Smith) show nl - 50 tab (+1 800-555-1212) show nl -(Name) bshow 50 tab (Joseph Smith) show nl - 50 tab (+1 800-555-1212) show nl -(Doctor) bshow 50 tab (Mahatma Ghandi) show nl - 50 tab (+1 800-555-1212) show nl - -hl - -(Conditions) bshow 50 tab (None) show nl -(Allergies) bshow 50 tab (None) show nl -(Meds) bshow 50 tab (None) show nl -(Blood) bshow 50 tab (A+++) show - 70 tab (I'm an Organ Donor!) bshow - -% Next page -154 0 translate - -5 240 star-of-life - -40 225 moveto -(info on other side) h1 nl -nl -nl -(You can put whatever you want here.) show nl - -showpage - -% Local Variables: -% mode: ps -% End: diff --git a/src/postscript/graph-paper.ps b/src/postscript/graph-paper.ps deleted file mode 100644 index 9ca374c..0000000 --- a/src/postscript/graph-paper.ps +++ /dev/null @@ -1,32 +0,0 @@ -%!PS-Adobe-3.0 -%%Title: A sheet of graph paper -%%Creator: Neale Pickett -%%CreationDate: Sun Oct 20 17:10:42 2002 -%%EndComments - -64 dict begin - -% How wide do you want the cells to be? (in mm) -/l 5 def - -% How light should the lines be? 0.0 is black, 1.0 is white (no lines). -0.9 setgray - -%%%%%%%%%%%%%%%%%%%%%%%%% -% You don't need to change anything below here - -% One millimeter in points -/mm 2.8452756 def - -0 l mm mul 900 { - dup 0 moveto - 0 900 rlineto - - 0 exch moveto - 900 0 rlineto -} for -stroke - -end -showpage -%%EOF diff --git a/src/postscript/index.head.md b/src/postscript/index.head.md deleted file mode 100644 index 0aa85f1..0000000 --- a/src/postscript/index.head.md +++ /dev/null @@ -1,5 +0,0 @@ -Title: PostScript Hacks - -One morning I woke up wondering, "how difficult could PostScript really be?" - -Answer: Not very. diff --git a/src/postscript/logo.ps b/src/postscript/logo.ps deleted file mode 100644 index 30275ca..0000000 --- a/src/postscript/logo.ps +++ /dev/null @@ -1,34 +0,0 @@ -%!PS-Adobe-3.0 EPSF-3.0 -%%BoundingBox: 0 0 612 792 -%%Title: Some functions to make PostScript feel like LOGO -%%Creator: Neale Pickett -%%CreationDate: Tue Oct 22 09:23:22 2002 -%%EndComments - -64 dict begin -/pen true def -/pu { /pen false def } def -/pd { /pen true def } def -/fd { /l exch def pen { 0 l rlineto } { 0 l rmoveto } ifelse } def -/rt { rotate } def -/lt { -1 mul rotate } def -/home { 306 496 moveto } def -home - -%% Your LOGO-like program starts here - -% a square -40 fd -90 rt -40 fd -90 rt -40 fd -90 rt -40 fd -stroke - -%% Your LOGO-like program ends here - -end -showpage -%%EOF diff --git a/src/postscript/page_dimensions.ps b/src/postscript/page_dimensions.ps deleted file mode 100644 index 394c9c3..0000000 --- a/src/postscript/page_dimensions.ps +++ /dev/null @@ -1,117 +0,0 @@ -%!PS-Adobe-2.0 -%Description: Displays dimensions of the page, and where your printer clips. - -/TM 792 def -/RM 612 def - -/margin 18 def -/linelen 18 def - -/step 18 def - - -.1 setlinewidth -/ruler { - newpath - - 0 0 moveto - 0 1 18 { - 0 6 rlineto - 1 -6 rmoveto - } for - - 0 0 moveto - 0 3 18 { - 0 12 rlineto - 3 -12 rmoveto - } for - - 9 0 moveto - 0 15 rlineto - - 0 0 moveto - 0 18 rlineto - 18 0 moveto - 0 18 rlineto - - stroke -} def - - -/Times-Roman findfont 10 scalefont setfont - - -/str 20 string def -0 step TM { - dup dup - margin exch - gsave - translate - - 0 0 moveto - step 2 mul le { - pop - } { - 18 0 rmoveto - str cvs str show - } ifelse - 0 18 translate - -90 rotate - ruler - - grestore -} for - -/str 20 string def -newpath -0 step RM { - dup dup - margin - gsave - translate - 0 0 moveto - - step 2 mul le { - pop - } { - 0 18 rmoveto - str cvs str show - } ifelse - ruler - grestore -} for - -1 setlinewidth - -% Score 1" in on all sides -newpath - -72 0 moveto -0 36 rlineto - -72 TM moveto -0 -36 rlineto - -RM 72 sub 0 moveto -0 36 rlineto - -RM 72 sub TM moveto -0 -36 rlineto - - -0 72 moveto -36 0 rlineto - -RM 72 moveto --36 0 rlineto - -0 TM 72 sub moveto -36 0 rlineto - -RM TM 72 sub moveto --37 0 rlineto - -stroke - - -showpage diff --git a/src/postscript/ruled-paper.ps b/src/postscript/ruled-paper.ps deleted file mode 100644 index c86effa..0000000 --- a/src/postscript/ruled-paper.ps +++ /dev/null @@ -1,95 +0,0 @@ -%!PS-Adobe-3.0 -%%Title: A sheet of ruled paper -%%Creator: Neale Pickett -%%CreationDate: Sun Oct 20 17:10:42 2002 -%%Pages: 1 -%%BoundingBox: 0 0 612 792 -%%EndComments - - -% Body height (in mm) -% 9 - big chief -% 5 - wide -% 4 - average -% 3 - teensy -/bh 9 def - - -%%%%%%%%%%%%%%%%%%%%%%%%% -% You don't need to change anything below here - - -% How much additional space between lines (mm)? -/ls 0 def - -% Show waist line? -/wl true def - -% Show ascenders and descenders? -/ad false def - -9 bh le { - /ls 4 def - /wl true def - /ad true def -} if - -5 bh eq { - /ls 2 def -} if - - -%%%%%%%%%%%%%%%%%%%%%%%%% -% You really don't need to change anything below here - -% One millimeter in points -/mm 2.8452756 def - -% Distance from baseline to baseline, in points -/lp bh 2 mul ls add mm mul def - -% Body height, in points -/bp bh mm mul def - -792 lp sub lp neg 0 { - 20 exch moveto - - ad { - % ascender and descender - gsave - 0.9 setgray - 0 bp 2 div rmoveto - 900 0 rlineto - -900 bp rmoveto - 900 0 rlineto - stroke - grestore - } if - - % waist line - wl { - gsave - 0.7 setgray - 0 bp rmoveto - 900 0 rlineto - stroke - grestore - } if - - % left margin - gsave - 0.3 setgray - 0 bp rlineto - stroke - grestore - - % base line - gsave - 0.3 setgray - 900 0 rlineto - stroke - grestore -} for - -showpage -%%EOF diff --git a/src/postscript/skel.ps b/src/postscript/skel.ps deleted file mode 100644 index 6eb25df..0000000 --- a/src/postscript/skel.ps +++ /dev/null @@ -1,273 +0,0 @@ -%!PS-Adobe-2.0 -%%Title: Skeleton for typesetting in PostScript. -%%Creator: Neale Pickett -%%CreationDate: Thu Nov 22 15:27:53 MST 1998 -%% Time-stamp: <2002-10-22 09:34:13 neale> -%%EndComments - -/FontSize 12 def - -/RegFont /Times-Roman def -/BoldFont /Times-Bold def -/ItalFont /Times-Italic def - -/RegFSet RegFont findfont FontSize scalefont def -/BoldFSet BoldFont findfont FontSize scalefont def -/HeadFSet BoldFont findfont FontSize 1.1 mul scalefont def -/ItalFSet ItalFont findfont FontSize scalefont def - -/SetRegFont { RegFSet setfont } def -/SetBoldFont { BoldFSet setfont } def -/SetHeadFont { HeadFSet setfont } def -/SetItalFont { ItalFSet setfont } def - -/LM 50 def -/BM 50 def -/RM 580 LM sub def -/TM 760 BM sub def - -/indentLevel 30 def - -% Re-set the margins -/reset_margins { - /lm LM def - /rm RM def -} def - -reset_margins - -% Move down just a little -/down { - reset_margins - lm indentation add currentpoint exch pop - FontSize 3 div sub - moveto -} def - -% Move to the next line -/next { - reset_margins - lm indentation add currentpoint exch pop % LM Y - FontSize 1.1 mul sub % LM Y' - moveto - currentpoint exch pop - BM lt { - showpage - LM TM moveto - } {} ifelse -} def - -% Move to the previous line -/prev { - lm indentation add currentpoint exch pop % LM Y - FontSize 1.1 mul add % LM Y' - moveto -} def - -% Re-align the indentation -/align { - lm indentation add currentpoint exch pop moveto -} def - -% Indent once -/indentation 0 def -/indent { - /indentation indentation indentLevel add def - align -} def - -% Deindent -/deindent { - /indentation indentation indentLevel sub def - align -} def - -% Show left justified -/lshow { - gsave - % Set the left margin - dup - stringwidth pop - LM add - /lm exch def - - currentpoint exch pop % (str) Y - LM exch % (str) x Y - moveto show - grestore -} def - -% Show centered -/cshow { - gsave - dup % (str) (str) - stringwidth pop % (str) x - 2 div % (str) x/2 - RM LM sub 2 div % (str) x/2 RM/2 - exch sub LM add % (str) x' - currentpoint exch pop % (str) x' Y - moveto show - grestore -} def - -% Show right justified -/rshow { - gsave - dup % (str) (str) - stringwidth pop % (str) x - - % set the right margin - dup - RM exch sub padwidth sub - /rm exch def - - RM exch sub % (str) x' - currentpoint exch pop % (str) x' Y - moveto show - grestore -} def - -% Show in a bold font -/bshow { - SetBoldFont - show - SetRegFont -} def - -% Show in a italics font -/ishow { - SetItalFont - show - SetRegFont -} def - -% Special parsing stuff; returns true if it's a printing character -/parse_special { - /word exch def - () word eq { - SetBoldFont - false - } { - () word eq { - SetItalFont - false - } { - () word eq { - SetRegFont - false - } { - true - } ifelse - } ifelse - } ifelse -} def - -% I totally stole this out of the blue book. But I changed it a lot, so -% you might not recognize it if not for the name. -/wordbreak ( ) def -/BreakIntoLines { - /proc exch def - /linelength exch def - /textstring exch def - /curwidth exch def - - /breakwidth wordbreak stringwidth pop def - /lastwordbreak 0 def - - /startchar 0 def - /restoftext textstring def - - SetRegFont - { - restoftext wordbreak search - - { - /done false def - } { - () exch - wordbreak exch - /done true def - } ifelse - - /nextword exch def pop - /restoftext exch def - - nextword parse_special { - /wordwidth nextword stringwidth pop def - curwidth wordwidth add linelength gt - { - % This word should go on the next line - proc - /curwidth exch def - } if - - /curwidth curwidth wordwidth add - breakwidth add def - nextword show - wordbreak show - - /lastwordbreak lastwordbreak - nextword length add 1 add def - - done { - exit - } { - } ifelse - } if - } loop - /lastchar textstring length def - textstring startchar lastchar startchar sub - getinterval proc -} def - -% Show some text, and word-wrap it if necessary, then move to the next line -/wshow { - 0 exch - /x currentpoint pop def - rm x sub % Line length - { - next - x currentpoint exch pop moveto - 0 - } - BreakIntoLines -} def - -% Show indented, wrapped text -/iwshow { - indentLevel exch - /x currentpoint pop def - rm x sub - indentLevel 0 rmoveto - { - next - x currentpoint exch pop moveto - 0 - } - BreakIntoLines -} def - -% Show inverse-indented, wrapped text -/iiwshow { - indentLevel neg exch - /x currentpoint pop indentLevel add def - rm x sub - { - next - x currentpoint exch pop moveto - 0 - } - BreakIntoLines - indentLevel neg 0 rmoveto -} def - - -LM TM moveto -SetRegFont - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Content goes here ;-) - - - -showpage \ No newline at end of file diff --git a/src/pysieved.md b/src/pysieved.md deleted file mode 100644 index 84e771b..0000000 --- a/src/pysieved.md +++ /dev/null @@ -1,4 +0,0 @@ -Title: pysieved: Python Managesieve Server - -pysieved is a GPL managesieve server. It is now hosted on gitorious, at -. diff --git a/src/pysieved/index.md b/src/pysieved/index.md deleted file mode 120000 index 498ed87..0000000 --- a/src/pysieved/index.md +++ /dev/null @@ -1 +0,0 @@ -../pysieved.mdwn \ No newline at end of file diff --git a/src/python/htmlpp.py b/src/python/htmlpp.py deleted file mode 100755 index 96af002..0000000 --- a/src/python/htmlpp.py +++ /dev/null @@ -1,100 +0,0 @@ -#! /usr/bin/env python - -## htmlpp -- Python HTML/CSS pretty-printer -## -## Thanks to ActiveState's ASPN (which rules, thanks guys) for leading -## me to this idea. AFAIK, they got the idea from MoinMoin. -## -## This is a part of epy: http://woozle.org/~neale/src/epy/ - -from __future__ import generators -import cgi -import sys -import keyword -import token -import tokenize - -def prettyprint(fd): - """Pretty print code into HTML/CSS. - - This returns a generator, which generates tokens to be printed to - some HTML document. You'll need to define a style sheet to get the - colors you like. - - """ - - end = (0, 0) - last = (None,) * 5 - for tok in tokenize.generate_tokens(fd.readline): - start = tok[2] - if start[1] != end[1]: - if start[0] != end[0]: - # What to do here? Punt. - yield '\nprettyprint punting: %s %s\n' % (tok, end) - else: - yield tok[4][end[1]:start[1]] - end = tok[3] - if end[1] == len(tok[4]): - # Prevent punting on newlines - end = (end[0] + 1, 0) - if tok[0] == token.NAME: - if keyword.iskeyword(tok[1]): - style = 'KEYWORD' - elif last[1] in ('class', 'def'): - style = 'FUNCTION' - else: - style = 'NAME' - else: - style = token.tok_name.get(tok[0]) - s = tok[1].expandtabs() - txt = cgi.escape(s) - if style: - last = tok - yield ('%s' - % (style, txt)) - else: - yield s - -def pp_fd(f, out=sys.stdout): - """Pretty print a file object.""" - - for item in prettyprint(f): - out.write(item) - -def pp_file(filename, out=sys.stdout): - """Pretty print a filename. - - Open and pretty-print python source in filename. Output goes to out - (default, sys.stdout). - - """ - - pp_fd(open(filename), out) - -def pp_string(string, out=sys.stdout): - """Pretty print a string.""" - - import cStringIO as StringIO - - f = StringIO.StringIO(string) - pp_fd(f, out) - -if __name__ == "__main__": - import sys - - print ''' - - - Bee-yoo-ti-ful source code - - - ''' - print '
'
-    # write colorized version to stdout
-    for item in prettyprint(sys.stdin):
-        sys.stdout.write(item)
-    print '
' - - diff --git a/src/python/index.head.md b/src/python/index.head.md deleted file mode 100644 index c54e246..0000000 --- a/src/python/index.head.md +++ /dev/null @@ -1,3 +0,0 @@ -Title: Python hacks - -Here's some junk I did in Python. diff --git a/src/python/kmp.py b/src/python/kmp.py deleted file mode 100755 index 221c662..0000000 --- a/src/python/kmp.py +++ /dev/null @@ -1,42 +0,0 @@ -#! /usr/bin/env python - -# Description: Knuth-Morris-Pratt algorithm - -"""Knuth-Morris-Pratt algorithm - -This is a direct transaltion of the KMP algorithm in the book -"Introduction to Algorithms" by Cormen, Lieserson, and Rivest. See that -book for an explanation of why this algorithm works. It's pretty cool. - -The only things I changed were some offsets, to cope with the fact that -Python arrays are 0-offset. - -""" - -__author__ = 'Neale Pickett ' - -def compute_prefix_function(p): - m = len(p) - pi = [0] * m - k = 0 - for q in range(1, m): - while k > 0 and p[k] != p[q]: - k = pi[k - 1] - if p[k] == p[q]: - k = k + 1 - pi[q] = k - return pi - -def kmp_matcher(t, p): - n = len(t) - m = len(p) - pi = compute_prefix_function(p) - q = 0 - for i in range(n): - while q > 0 and p[q] != t[i]: - q = pi[q - 1] - if p[q] == t[i]: - q = q + 1 - if q == m: - return i - m + 1 - return -1 diff --git a/src/python/lousycron.py b/src/python/lousycron.py deleted file mode 100755 index 359d579..0000000 --- a/src/python/lousycron.py +++ /dev/null @@ -1,68 +0,0 @@ -#! /usr/bin/python - -## cronit -- A lightweight (aka "lousy") anacron replacement -## Copyright (C) 2007 Neale Pickett -## -## This program is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or (at -## your option) any later version. -## -## This program is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with this program. If not, see . - -import time -import os -import popen2 -import socket - -basedir = os.path.expanduser('~/lib/cron') - -os.chdir(os.path.expanduser('~')) - -now = time.time() -periods = (('test', -1), - ('hourly', 3600), - ('daily', 86400), - ('weekly', 604800), - ('monthly', 18144000), # more or less - ('yearly', 2204892000)) - -def run_parts(dir): - out = [] - for script in os.listdir(dir): - if script.endswith('~') or script.startswith('.'): - continue - fn = os.path.join(dir, script) - proc = popen2.Popen4(fn) - proc.tochild.close() - outstr = proc.fromchild.read() - ret = proc.wait() - if outstr or ret: - out.append((fn, outstr, ret)) - return out - -def cronit(basedir): - for name, interval in periods: - dir = os.path.join(basedir, name) - if not os.path.exists(dir): - continue - tsfile = os.path.join(dir, '.timestamp.%s' % socket.gethostname()) - try: - ts = int(file(tsfile).read().strip()) - except: - ts = 0 - if ts + interval < now: - problems = run_parts(dir) - file(tsfile, 'w').write('%d\n' % now) - for script, output, ret in problems: - print '====== %s exited with code %d' % (script, ret/256) - print output - -if __name__ == '__main__': - cronit(basedir) diff --git a/src/python/maildir.py b/src/python/maildir.py deleted file mode 100644 index cfe7ddf..0000000 --- a/src/python/maildir.py +++ /dev/null @@ -1,46 +0,0 @@ -# maildir.py -- Maildir utilities -# -# Released into the public domain - -"""Maildir utilities""" - -__author__ = 'Neale Pickett ' - -import os -import socket -import time - -# Counter gets incremented by one for every message delivered -count = 0 - -# Local hostname -HOST = socket.gethostname() - -def create(mdir): - os.umask(0022) - for i in ('tmp', 'cur', 'new'): - os.makedirs('%s/%s' % (mdir, i)) - -def write(mdir, message, info=None): - """Write a message out to a maildir. - - """ - global count - - mdir = time.strftime('%Y-%m') - if not os.path.exists(mdir): - maildir_create(mdir) - - filename = '%d.%d_%04d.%s' % (time.time(), os.getpid(), - count, HOST) - f = open('%s/tmp/%s' % (mdir, filename), - 'w') - f.write(message) - f.close() - if info: - os.rename('%s/tmp/%s' % (mdir, filename), - '%s/cur/%s:2,%s' % (mdir, filename, info)) - else: - os.rename('%s/tmp/%s' % (mdir, filename), - '%s/new/%s' % (mdir, filename)) - count += 1 diff --git a/src/python/ndstrunc.py b/src/python/ndstrunc.py deleted file mode 100755 index 30fff6b..0000000 --- a/src/python/ndstrunc.py +++ /dev/null @@ -1,54 +0,0 @@ -#! /usr/bin/python - -### ndstrunc -- Trims .nds ROM files - - -import struct -import optparse -import os - -parser = optparse.OptionParser(description='Trims .nds ROM files.') -parser.add_option('-d', '--dry-run', - action='store_false', dest='writeout', default=True, - help="Don't actually modify any files.") -parser.add_option('-f', '--force', - action='store_true', dest='force', default=False, - help="Force truncation even if it seems like too much.") -(options, args) = parser.parse_args() - -for fn in args: - f = file(fn, 'rb+') - f.seek(0x80) - (size,) = struct.unpack('= ondisk: - print ' Already truncated.' - continue - - print ' On disk:', ondisk - print ' Header says:', size - print ' Would save: %dB (%2.0f%%)' % (ondisk-size, reduction) - if size < (ondisk >> 2): - if options.force: - print ' Truncating anyway, as requested.' - else: - print ' Would truncate too much!!' - continue - if options.writeout: - f.truncate(size) - print ' Truncated.' - - - diff --git a/src/python/robotfindskitten.py b/src/python/robotfindskitten.py deleted file mode 100644 index aecf026..0000000 --- a/src/python/robotfindskitten.py +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/env python - -"""robotfindskitten -- A zen simulation. - -This is a web version of the classic text-based game. The text-based -version is much better. Go check it out at http://robotfindskitten.org/ - -""" - -import cgitb; cgitb.enable() -import cgi -import whrandom -import sys - -symbols = list('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"$%&\'()*+,-./:;<=>?@[\]^_`{|}~') -width = 50 -height = 30 - -def color(): - def c(): - return whrandom.choice(('44', '88', 'cc', 'ff')) - - return c() + c() + c() - -print 'Content-type: text/html' -print - -def main(): - nki = [] - f = open('messages.h') - for line in f.xreadlines(): - if line.startswith(' "'): - line = line.strip() - if line[-1] == ',': - line = line[1:-2] - else: - line = line[1:-1] - line = line.replace(r'\"', '"') - nki.append(line) - - print ''' - robotfindskitten: a zen simulation - - - ''' % color() - - print '' - - print '

robotfindskitten

' - - print ''' -

- You are robot. Your mission: find kitten. - - - Hold the mouse cursor over an object you suspect to be kitten. - After a few seconds, your browser will tell you what you have - found. Older browsers may not be able to relay what an object - actually is, so the experience may be diminished somewhat. -

- - ''' - - - print '
'
-
-    screen = []
-    for i in range(height):
-        screen.append([' '] * width)
-
-    for i in range(30):
-        x = whrandom.randrange(width)
-        y = whrandom.randrange(height)
-
-        n = whrandom.randrange(len(symbols))
-        s = symbols[n]
-        del symbols[n]
-        s = cgi.escape(s)
-
-        n = whrandom.randrange(len(nki))
-        t = nki[n]
-        del nki[n]
-        t = cgi.escape(t)
-        t = t.replace('"', '"')
-
-        screen[y][x] = ('%s'
-                        % (color(), t, s))
-    # place kitten!
-    screen[y][x] = '%s' % s
-
-    for row in screen:
-        print ''.join(row)
-
-    print '
' - - print '' - -if __name__ == '__main__': - main() - diff --git a/src/python/snpplib.py b/src/python/snpplib.py deleted file mode 100644 index 20f3b79..0000000 --- a/src/python/snpplib.py +++ /dev/null @@ -1,538 +0,0 @@ -#! /usr/bin/env python - -# Description: SNPP client class for Python - -'''SNPP client class. - -Author: Neale Pickett - -This was modified from the Python 1.5 library SMTP lib. -Which was modified from the Python 1.5 library HTTP lib. - -Basically, I took smtplib, did an s/SMTP/SNPP/, and changed about ten -other things. If only all projects were this easy :-) - -Example: - - >>> import snpplib - >>> s = snpplib.SNPP("localhost") - >>> print s.help()[1] - - Level 1 commands accepted: - - PAGEr - MESSage - RESEt - SEND - QUIT - HELP - - Level 2 commands accepted: - - DATA - LOGIn [password] - LEVEl - COVErage - HOLDuntil [+/-GMTdifference] - CALLerid - - Level 3 commands accepted: - - none - - OK - >>> s.putcmd("rese") - >>> s.getreply() - (250, 'Reset ok') - >>> s.quit() -''' - -import socket -import re -import rfc822 -import types - -SNPP_PORT = 444 -CRLF="\r\n" - -# Exception classes used by this module. -class SNPPException(Exception): - """Base class for all exceptions raised by this module.""" - -class SNPPServerDisconnected(SNPPException): - """Not connected to any SNPP server. - - This exception is raised when the server unexpectedly disconnects, - or when an attempt is made to use the SNPP instance before - connecting it to a server. - """ - -class SNPPResponseException(SNPPException): - """Base class for all exceptions that include an SNPP error code. - - These exceptions are generated in some instances when the SNPP - server returns an error code. The error code is stored in the - `snpp_code' attribute of the error, and the `snpp_error' attribute - is set to the error message. - """ - - def __init__(self, code, msg): - self.snpp_code = code - self.snpp_error = msg - self.args = (code, msg) - -class SNPPSenderRefused(SNPPResponseException): - """Caller ID refused. - - In addition to the attributes set by on all SNPPResponseException - exceptions, this sets `sender' to the string that the SNPP refused - """ - - def __init__(self, code, msg, sender): - self.snpp_code = code - self.snpp_error = msg - self.sender = sender - self.args = (code, msg, sender) - -class SMTPRecipientsRefused(SNPPResponseException): - """All recipient addresses refused. - - The errors for each recipient are accessable thru the attribute - 'recipients', which is a dictionary of exactly the same sort as - SNPP.sendpage() returns. - """ - - def __init__(self, recipients): - self.recipients = recipients - self.args = ( recipients,) - - -class SNPPDataError(SNPPResponseException): - """The SNPP server didn't accept the data.""" - -class SNPPConnectError(SNPPResponseException): - """Error during connection establishment""" - -def quotedata(data): - """Quote data for email. - - Double leading '.', and change Unix newline '\n', or Mac '\r' into - Internet CRLF end-of-line. - """ - return re.sub(r'(?m)^\.', '..', - re.sub(r'(?:\r\n|\n|\r(?!\n))', CRLF, data)) - -class SNPP: - """This class manages a connection to an SNPP server. - SNPP Objects: - - For method docs, see each method's docstrings. In general, there is - a method of the same name to perform each SNPP command, and there - is a method called 'sendpage' that will do an entire page - transaction. - """ - debuglevel = 0 - file = None - - def __init__(self, host = '', port = 0): - """Initialize a new instance. - - If specified, `host' is the name of the remote host to which to - connect. If specified, `port' specifies the port to which to connect. - By default, snpplib.SNPP_PORT is used. An SNPPConnectError is - raised if the specified `host' doesn't respond correctly. - - """ - self.esnpp_features = {} - if host: - (code, msg) = self.connect(host, port) - if code != 220: - raise SNPPConnectError(code, msg) - - def set_debuglevel(self, debuglevel): - """Set the debug output level. - - A non-false value results in debug messages for connection and for all - messages sent to and received from the server. - - """ - self.debuglevel = debuglevel - - def connect(self, host='localhost', port = 0): - """Connect to a host on a given port. - - If the hostname ends with a colon (`:') followed by a number, and - there is no port specified, that suffix will be stripped off and the - number interpreted as the port number to use. - - Note: This method is automatically invoked by __init__, if a host is - specified during instantiation. - - """ - if not port: - i = host.find(':') - if i >= 0: - host, port = host[:i], host[i+1:] - try: - port = int(port) - except ValueError: - raise socket.error, "nonnumeric port" - if not port: port = SNPP_PORT - self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - if self.debuglevel > 0: print 'connect:', (host, port) - self.sock.connect((host, port)) - (code,msg)=self.getreply() - if self.debuglevel >0 : print "connect:", msg - return (code,msg) - - def sendstr(self, str): - """Send `str' to the server.""" - if self.debuglevel > 0: print 'send:', `str` - if self.sock: - try: - self.sock.send(str) - except socket.error: - raise SNPPServerDisconnected('Server not connected') - else: - raise SNPPServerDisconnected('please run connect() first') - - def putcmd(self, cmd, args=""): - """Send a command to the server.""" - str = '%s %s%s' % (cmd, args, CRLF) - self.sendstr(str) - - def getreply(self): - """Get a reply from the server. - - Returns a tuple consisting of: - - - server response code (e.g. '250', or such, if all goes well) - Note: returns -1 if it can't read response code. - - - server response string corresponding to response code (multiline - responses are converted to a single, multiline string). - - Raises SNPPServerDisconnected if end-of-file is reached. - """ - resp=[] - if self.file is None: - self.file = self.sock.makefile('rb') - while 1: - line = self.file.readline() - if line == '': - self.close() - raise SNPPServerDisconnected("Connection unexpectedly closed") - if self.debuglevel > 0: print 'reply:', `line` - resp.append(line[4:].strip()) - code=line[:3] - # Check that the error code is syntactically correct. - # Don't attempt to read a continuation line if it is broken. - try: - errcode = int(code) - except ValueError: - errcode = -1 - break - # Check if multiline response. - if errcode != 214: - break - - errmsg = '\n'.join(resp) - if self.debuglevel > 0: - print 'reply: retcode (%s); Msg: %s' % (errcode,errmsg) - return errcode, errmsg - - def docmd(self, cmd, args=""): - """Send a command, and return its response code.""" - self.putcmd(cmd,args) - return self.getreply() - - def help(self, args=''): - """SNPP 'help' command. - Returns help text from server.""" - return self.docmd("help", args) - - def rese(self): - """SNPP 'rese' command -- resets session.""" - return self.docmd("rese") - - def page(self, pagerid, password=""): - """SNPP 'page' command -- specifies a pager ID. - - - - """ - - if password: - args = "%s %s" % (pagerid, password) - else: - args = pagerid - return self.docmd("page", args) - - def mess(self, msg): - """SNPP 'mess' command -- sends a single-line message.""" - return self.docmd("mess", msg) - - def send(self): - """SNPP 'send' command -- sends a message.""" - return self.docmd("send") - - def data(self, msg): - """SNPP 'DATA' command -- sends message data to server. - - Automatically quotes lines beginning with a period per rfc821. - Raises SNPPDataError if there is an unexpected reply to the - DATA command; the return value from this method is the final - response code received when the all data is sent. - """ - self.putcmd("data") - (code,repl)=self.getreply() - if self.debuglevel >0 : print "data:", (code,repl) - if code <> 354: - raise SNPPDataError(code,repl) - else: - self.sendstr(quotedata(msg)) - self.sendstr("%s.%s" % (CRLF, CRLF)) - (code,msg)=self.getreply() - if self.debuglevel >0 : print "data:", (code,msg) - return (code,msg) - - # Level 2 - Optional Extensions - - def logi(self, loginid, password=""): - """SNPP 'logi' command -- logs in to the server. - - This command allows for a session login ID to be specified. It - is used to validate the person attempting to access the paging - terminal. If no LOGIn command is issued, "anonymous" user - status is assumed. - - """ - - if password: - args = "%s %s" % (loginid, password) - else: - args = loginid - return self.docmd("logi", args) - - def leve(self, servicelevel): - """SNPP 'leve' command -- sets server level for next PAGE. - - The LEVEl function is used to specify an optional alternate - level of service for the next PAGEr command. Ideally, - "ServiceLevel" should be an integer between 0 and 11 inclusive. - The TME protocol specifies ServiceLevel as follows: - - 0 - Priority - 1 - Normal (default) - 2 - Five minutes - 3 - Fifteen minutes - 4 - One hour - 5 - Four hours - 6 - Twelve hours - 7 - Twenty Four hours - 8 - Carrier specific '1' - 9 - Carrier specific '2' - 10 - Carrier specific '3' - 11 - Carrier specific '4' - - """ - - return self.docmd("leve", servicelevel) - - def aler(self, alertoverride): - """SNPP 'aler' command -- override alert setting. - - The optional ALERt command may be used to override the default - setting and specify whether or not to alert the subscriber upon - receipt of a message. This option, like the previous command, - alters the parameters submitted to the paging terminal using - the PAGEr command. The TME protocol specifies AlertOverride as - either 0-DoNotAlert, or 1-Alert. - - """ - - return self.docmd("aler", alertoverride) - - def cove(self, alternatearea): - """SNPP 'cove' command -- override coverage area. - - The optional COVErage command is used to override the - subscriber's default coverage area, and allow for the selection - of an alternate region. This option, like the previous - command, alters the parameters submitted to the paging terminal - using the PAGEr command. AlternateArea is a designator for one - of the following: - - - A subscriber-specific alternate coverage area - - A carrier-defined region available to subscribers - - """ - - return self.docmd("cove", alternatearea) - - def hold(self, timespec, gmtdiff=""): - """SNPP 'hold' command -- hold until specified time. - - The HOLDuntil command allows for the delayed delivery of a - message, to a particular subscriber, until after the time - specified. The time may be specified in local time (e.g. local - to the paging terminal), or with an added parameter specifying - offset from GMT (in other words, "-0600" specifies Eastern - Standard Time). This option, like the previous command, alters - the parameters submitted to the paging terminal using the PAGEr - command. - - """ - - if gmtdiff: - args = "%s %s" % (timespec, gmtdiff) - else: - args = timespec - - return self.docmd("hold", args) - - def call(self, callerid): - """SNPP 'call' command -- specify caller ID. - - The CALLerid function is a message-oriented function (as opposed - to the subscriber-oriented functions just described). This - allows for the specification of the CallerIdentifier function as - described in TME. This parameter is optional, and is at the - discretion of the carrier as to how it should be implemented or - used. - - """ - - return self.docmd("call", callerid) - - def subj(self, messagesubject): - """SNPP 'subj' command -- specify a message subject. - - The SUBJect function allows is a message-oriented function that - allows the sender to specify a subject for the next message to - be sent. This parameter is optional and is at the discretion of - the carrier as to how it should be implemented or used. - - """ - - return self.docmd("subj", messagesubject) - - - # Level 3 -- Two-Way Extensions - - # I didn't implement these because I got tired of typing this stuff - # in, and I doubt anyone's going to use this anyhow, seeing as how - # qpage doesn't do any of these extensions. Although this may - # change. - - # some useful methods - def sendpage(self, from_id, to_ids, msg): - """This command performs an entire mail transaction. - - The arguments are: - - from_id : The CallerID sending this mail, or None to - not send any CallerID. - - to_ids : A list of pager IDs to send this page to. A - bare string will be treated as a list with 1 - address. - - msg : The message to send. - - This method will return normally if the page is accepted for at - least one recipient. It returns a dictionary, with one entry for - each recipient that was refused. Each entry contains a tuple of - the SNPP error code and the accompanying error message sent by - the server. - - This method may raise the following exceptions: - - SNPPRecipientsRefused The server rejected for ALL recipients - (no mail was sent). - SNPPSenderRefused The server didn't accept the from_id. - SNPPDataError The server replied with an unexpected - error code - - Note: the connection will be open even after an exception is raised. - - Example: - - >>> import snpplib - >>> s=snpplib.SNPP("localhost") - >>> tolist=["parsingh","rhiannon","saffola","bob"] - >>> msg = 'Hey guys, what say we have pizza for dinner?' - >>> s.sendpage("neale",tolist,msg) - { "bob" : ( 550 ,"User unknown" ) } - >>> s.quit() - - In the above example, the message was accepted for delivery to three - of the four addresses, and one was rejected, with the error code - 550. If all addresses are accepted, then the method will return an - empty dictionary. - - """ - (code,resp) = self.call(from_id) - if code <> 250: - # CallerID command not implemented, too bad. - pass - senderrs={} - if type(to_ids) == types.StringType: - to_ids = [to_ids] - for each in to_ids: - (code,resp)=self.page(each) - if (code <> 250) and (code <> 251): - senderrs[each]=(code,resp) - if len(senderrs)==len(to_ids): - # the server refused all our recipients - self.rese() - raise SNPPRecipientsRefused(senderrs) - (code,resp)=self.data(msg) - if code <> 250: - self.rese() - raise SNPPDataError(code, resp) - (code,resp)=self.send() - if code <> 250: - self.rese() - raise SNPPDataError(code, resp) - #if we got here then somebody got our page - return senderrs - - - def close(self): - """Close the connection to the SNPP server.""" - if self.file: - self.file.close() - self.file = None - if self.sock: - self.sock.close() - self.sock = None - - - def quit(self): - """Terminate the SNPP session.""" - self.docmd("quit") - self.close() - - -# Test the sendmail method, which tests most of the others. -# Note: This always sends to localhost. -if __name__ == '__main__': - import sys, rfc822 - - def prompt(prompt): - sys.stdout.write(prompt + ": ") - return sys.stdin.readline().strip() - - fromaddr = prompt("From") - toaddrs = prompt("To").split(',') - print "Enter message, end with ^D:" - msg = '' - while 1: - line = sys.stdin.readline() - if not line: - break - msg = msg + line - print "Message length is " + `len(msg)` - - server = SNPP('localhost') - server.set_debuglevel(1) - server.sendpage(fromaddr, toaddrs, msg) - server.quit() diff --git a/src/python/spampot.py b/src/python/spampot.py deleted file mode 100755 index 0ee0cb9..0000000 --- a/src/python/spampot.py +++ /dev/null @@ -1,325 +0,0 @@ -#! /usr/bin/env python - -### spampot.py -- Spam honeypot SMTP server -### Copyright (C) 2003 Neale Pikett -### Time-stamp: <2003-05-06 09:08:52 neale> -### -### This is free software; you can redistribute it and/or modify it -### under the terms of the GNU General Public License as published by -### the Free Software Foundation; either version 2, or (at your option) -### any later version. -### -### This program is distributed in the hope that it will be useful, but -### WITHOUT ANY WARRANTY; without even the implied warranty of -### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -### General Public License for more details. -### -### You should have received a copy of the GNU General Public License -### along with this software; see the file COPYING. If not, write to -### the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, -### USA. - -"""Spam honeypot SMTP server. - -This just sits on port 25 of whatever IP you pass in as an argument, and -spools every message out to MAILDIR. It tries to look like an old -Sendmail server, to maximize chances of being tagged as an open relay. - -""" - -import cStringIO as StringIO -import asynchat -import asyncore -import syslog -import smtplib -import rfc822 -import socket -import time -import sys -import os -import re -import struct -import maildir # get maildir.py from the same place you got this file - -# suid to this user -USER = 'spam' - -# host to relay probes for us -SMARTHOST = '127.0.0.1' - -# save multiple messages from the same IP? You probably don't want this -# -- it can consume a gigabyte a day. -SAVEDUPES = False - -# slow down if multiple mails are getting sent over a single connection? -# This could save bandwidth. -TARPIT = True - -# chroot to this directory and spool messages there -MAILDIR = '/home/spam/Maildir/spampot' - -# My hostname -HOST = socket.gethostname() - -# write to this PID file -PIDFILE = '/var/run/spampot.pid' - -# syslog levels (you shouldn't need to change this) -LEVELS = {'info': syslog.LOG_INFO, - 'warning': syslog.LOG_WARNING, - 'error': syslog.LOG_ERR} - -### - -# Hosts seen -seen = {} - -def shescape(str): - return "'" + str.replace("'", "'\"'\"'") + "'" - - -class Daemon: - """Helpful class to make a process a daemon""" - - def __init__(self, pidfile): - try: - f = file(pidfile, "r") - pid = int(f.read()) - f.close() - os.kill(pid, 0) - print "Already running at pid %d" % pid - sys.exit(1) - except (IOError, OSError, ValueError): - pass - self.pidf = file(pidfile, 'w') - - def daemonize(self): - self.pid = os.fork() - if self.pid: - self.pidf.write("%d\n" % self.pid) - sys.exit(0) - # Decouple from parent - self.pidf.close() - os.chdir("/") - os.setsid() - os.umask(0) - os.close(sys.stdin.fileno()) - os.close(sys.stdout.fileno()) - os.close(sys.stderr.fileno()) - syslog.syslog(syslog.LOG_INFO, "starting") - return self.pid - - def jail(self, root, user=None, group=None): - uid, gid = None, None - if group: - import grp - - gr = grp.getgrnam(group) - gid = gr[2] - if user: - import pwd - - pw = pwd.getpwnam(user) - uid = pw[2] - if not gid: gid = pw[3] - os.chroot(root) - os.chdir('/') - if gid: os.setgid(gid) - if uid: os.setuid(uid) - - -class Listener(asyncore.dispatcher): - """Listens for incoming socket connections and spins off - dispatchers created by a factory callable. - """ - - def __init__(self, bindaddr, port, - factory, factoryArgs=()): - asyncore.dispatcher.__init__(self) - self.factory = factory - self.factoryArgs = factoryArgs - self.create_socket(socket.AF_INET, socket.SOCK_STREAM) - self.set_reuse_addr() - self.bind((bindaddr, port)) - self.listen(40) - syslog.syslog(syslog.LOG_INFO, 'Listening on %s:%d' % (bindaddr, port)) - - def handle_accept(self): - # If an incoming connection is instantly reset, eg. by following a - # link in the web interface then instantly following another one or - # hitting stop, handle_accept() will be triggered but accept() will - # return None. - result = self.accept() - if result: - clientSocket, clientAddress = result - args = [clientSocket] + list(self.factoryArgs) - self.factory(*args) - - -class Server(asynchat.async_chat): - """A stupid SMTP server.""" - - def __init__(self, sock): - self.msg_count = 0 - self.host = 'internal.nat' - self.request = '' - self.hello = None - self.reset() - asynchat.async_chat.__init__(self) - self.set_socket(sock) - - def reset(self): - self.mailfrom = None - self.rcptto = [] - - def log(self, message): - syslog.syslog(syslog.LOG_INFO, message) - - def log_info(self, message, type='info'): - lvl = LEVELS.get(type, syslog.LOG_INFO) - syslog.syslog(lvl, message) - - def handle_connect(self): - self.peername = self.getpeername() - self.sockname = self.getsockname() - self.socknamehex = "%X" % struct.unpack('L', socket.inet_aton(self.sockname[0])) - self.set_terminator('\r\n') - - self.log('Connect from %s' % (self.peername,)) - now = time.localtime() - ts = time.strftime('%a, ' + str(now[2]) + ' %b %y %H:%M:%S %Z') - self.push("220 %s Sendmail ready at %s\r\n" % (self.host, ts)) - - def handle_close(self): - self.log('Close from %s; relayed %d messages' % (self.peername, self.msg_count)) - self.close() - - def collect_incoming_data(self, data): - self.request += data - - def envelope_found_terminator(self): - data = self.request - self.request = "" - command = data[:4].upper() - if command in ["HELO", "EHLO"]: - whom = data[5:].strip() - self.hello = whom - self.push("250 Hello %s, pleased to meet you.\r\n" % whom) - elif command == 'MAIL': - whom = data[10:].strip() - self.mailfrom = whom - self.push("250 %s... Sender ok\r\n" % whom) - elif command == 'RCPT': - whom = data[8:].strip() - self.rcptto.append(whom) - self.push("250 %s... Recipient ok\r\n" % whom) - elif command == "DATA": - self.set_terminator('\r\n.\r\n') - self.found_terminator = self.data_found_terminator - self.push('354 Enter mail, end with "." on a line by itself\r\n') - elif command == "QUIT": - self.push("221 %s closing connection\r\n" % self.host) - self.close_when_done() - elif command == "RSET": - self.reset() - self.push('250 Reset state\r\n') - else: - self.push("500 Command unrecognized\r\n") - found_terminator = envelope_found_terminator - - def data_found_terminator(self): - self.message = self.request - self.request = '' - self.set_terminator('\r\n') - self.found_terminator = self.envelope_found_terminator - self.deliver_message() - self.push("250 Mail accepted\r\n") - self.reset() - - def relay_message(self): - s = os.popen("/usr/lib/sendmail -f %s %s" - % (shescape(self.string), - ' '.join([shescape(s) for s in self.rcptto])), - 'w') - s.write(self.message) - s.close() - - probe_re = None - - def is_probe(self): - """Returns true if the current message is a probe message""" - - # Compile the probe regular expression the first time through - if not self.probe_re: - self.probe_re = re.compile(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|%s:25' % self.socknamehex, - re.IGNORECASE) - - # If it's not the first message this connection, it's probably - # not a probe. - if self.msg_count: - return False - - # Probes also don't have multiple recipients - if len(self.rcptto) != 1: - return False - - # And they're short - if len(self.message) > 1024: - return False - - # Check for the probe regex - if self.probe_re.search(self.message): - # we have a bite: now do some more intense investigation - f = StringIO.StringIO(self.message) - m = rfc822.Message(f) - - # IP address in subject? - subj = m.get('Subject') - if subj and subj.find(self.sockname[0]) != -1: - return True - - # Hex-encoded IP address anywhere in message? - if m.find(self.socknamehex) != -1: - return True - - return False - - def deliver_message(self): - global seen - - headers = [ - "SMTP-Date: %s" % time.ctime(), - "SMTP-Sock: %s:%d" % self.sockname, - "SMTP-Peer: %s:%d" % self.peername, - "SMTP-Hello: %s" % self.hello, - "SMTP-Mail-From: %s" % self.mailfrom, - "SMTP-Messages-This-Connection: %s" % self.msg_count, - ] - for t in self.rcptto: - headers.append("SMTP-Rcpt-To: %s" % t) - if self.is_probe(): - self.relay_message() - self.log('Relayed probe from=%s to=%s' % (self.mailfrom, self.rcptto)) - headers.append("SMTP-Relayed: Yes") - msg_count = seen.get(self.peername) + 1 - seen[self.peername] = msg_count - if msg_count in (0, 1, 2, 3, 4, 8, 64, 512, 4096, 32768, 262144): - # Hopefully nobody running this will ever hit that last one ;) - msg = '\r\n'.join(headers) + '\r\n' + self.message - m = maildir.write(time.strftime('%Y-%m'), msg) - self.log('Trapped from=%s to=%s msg_count=%d' % (self.mailfrom, self.rcptto, msg_count)) - self.msg_count += 1 - - -def main(): - dmn = Daemon(PIDFILE) - syslog.openlog('spampot', syslog.LOG_PID, syslog.LOG_MAIL) - listener = Listener(sys.argv[1], 25, Server) - dmn.jail(MAILDIR, USER) - dmn.daemonize() - asyncore.loop() - - -if __name__ == '__main__': - main() - diff --git a/src/python/status.py b/src/python/status.py deleted file mode 100755 index a2e14e6..0000000 --- a/src/python/status.py +++ /dev/null @@ -1,329 +0,0 @@ -#! /usr/bin/python - -"""Status dealiemajigger for dzen2 (or others, probably). - -This outputs: - - * Debian packages in need of upgrade (if you have the apt module) - * master volume (if you have alsa) - * battery life (if you have a battery) - * load average if it goes over 0.25 - * current date and time - -It prints it again whenever any of these change. It also watches for Mute, -Volume Up, and Volume Down key events on multimedia keyboards, and adjusts -the mixer appropriately. - -Lastly, it registers itself with D-Bus so you can send yourself notices -like so: - - $ dbus-send --dest=org.woozle.Status \ - /org/woozle/Status \ - org.woozle.Status.notice \ - string:'this is where your message goes' - -They will show up green in dzen2. - -This only polls the ALSA mixer settings, and those only every minute. -Master mixer changes will take from 0 to 60 seconds to register if you -don't use the multimedia keys on your keyboard. - -You need to be running HAL for this to do much other than tell you -the time. Don't worry, HAL is pretty small. - -""" - -import signal -import dbus -import dbus.service -import sys -import os -import gobject -import time -from sets import Set -try: - import apt - import socket -except ImportError: - apt = None - -try: - import alsaaudio -except ImportError: - alsaaudio = None - -# Set to true if you want dzen2 colors -dzen2 = False - -def color(name, text): - if dzen2: - return '^fg(%s)%s^fg()' % (name, text) - else: - return '-=[ %s ]=-' % text - -class Status(dbus.service.Object): - debug = False - - def __init__(self, *args, **kwargs): - dbus.service.Object.__init__(self, *args, **kwargs) - - self.system_bus = dbus.SystemBus() - - self.hal_manager = self.system_bus.get_object('org.freedesktop.Hal', - '/org/freedesktop/Hal/Manager') - self.hal_computer = self.system_bus.get_object('org.freedesktop.Hal', - '/org/freedesktop/Hal/devices/computer') - - # Listen for HAL events - self.system_bus.add_signal_receiver(self.handle_hal_event, - dbus_interface='org.freedesktop.Hal.Device', - path_keyword='path', - member_keyword='member') - - # For now I only care about battery 0. - batteries = self.hal_manager.FindDeviceByCapability('battery', - dbus_interface='org.freedesktop.Hal.Manager') - if batteries: - bat = self.system_bus.get_object('org.freedesktop.Hal', - batteries[0]) - self.battery = dbus.Interface(bat, - dbus_interface='org.freedesktop.Hal.Device') - else: - self.battery = None - - # Audio mixer, if we have the ALSA module installed. - if alsaaudio: - try: - self.mixer = alsaaudio.Mixer() - except alsaaudio.ALSAAudioError: - # Some weird mixers have no Master control (eg. Mac Mini) - self.mixer = alsaaudio.Mixer('PCM') - except ImportError: - self.mixer = None - else: - self.mixer = None - - # How many debian packages can be upgraded? - self.upgradable = [] - - # All my children - self.pids = Set() - - def run(self, file, *args): - pid = os.spawnlp(os.P_NOWAIT, file, file, *args) - self.pids.add(pid) - - def battery_level(self): - if self.battery: - return self.battery.GetProperty('battery.charge_level.percentage') - - def battery_capacity_state(self): - if self.battery: - try: - return self.battery.GetProperty('battery.charge_level.capacity_state') - except dbus.exceptions.DBusException: - bat = self.battery_level() - if bat > 20: - return 'ok' - else: - return 'battery low' - - def suspend(self, num_secs_to_wakeup=0): - def ignore(*d): - pass - - self.run('screenlock') - self.hal_computer.Suspend(num_secs_to_wakeup, - dbus_interface='org.freedesktop.Hal.Device.SystemPowerManagement', - reply_handler=ignore, - error_handler=ignore) - - def muted(self): - if self.mixer: - try: - return self.mixer.getmute()[0] - except alsaaudio.ALSAAudioError: - pass - raise ValueError('No mute control') - - def toggle_mute(self): - try: - mute = self.muted() - self.mixer.setmute(not mute) - self.update() - except ValueError: - pass - - @dbus.service.method('org.woozle.Status', - in_signature='d') - def adjust_volume(self, adj): - if self.mixer: - vol = self.mixer.getvolume()[0] - vol += adj - vol = min(vol, 100) - vol = max(vol, 0) - self.mixer.setvolume(vol) - self.update() - - def volume(self): - if self.mixer: - try: - mute = self.muted() - except ValueError: - mute = False - if mute: - return '--' - else: - return str(self.mixer.getvolume()[0]) - - def handle_button_pressed(self, button, path): - if button == 'lid': - lid = self.system_bus.get_object('org.freedesktop.Hal', - path) - if (lid.GetProperty('button.state.value', - dbus_interface='org.freedesktop.Hal.Device') and - not os.path.exists(os.path.expanduser('~/nosusp'))): - self.suspend() - elif button == 'mute': - self.toggle_mute() - elif button == 'volume-down': - self.adjust_volume(-5) - elif button == 'volume-up': - self.adjust_volume(+5) - elif button == 'sleep': - self.suspend() - elif self.debug: - self.update('button pressed: %s' % button) - - def handle_property_modified(self, name, added, removed): - if name == 'battery.charge_level.percentage': - self.update() - elif name.startswith('battery.'): - pass - else: - self.update('property modified: %s' % name) - - def handle_hal_event(self, *d, **k): - member = k.get('member') - if member == 'Condition': - if d[0] == 'ButtonPressed': - self.handle_button_pressed(d[1], k.get('path')) - elif member == 'PropertyModified': - assert int(d[0]) == len(d[1]) - for p in d[1]: - self.handle_property_modified(*p) - else: - self.update('%s: %s' % (d, kwargs)) - - def update(self, msg=None): - out = [] - if msg: - out.append(color('green', msg)) - - if self.upgradable: - out.append(color('cyan', '%d upgradable packages' % self.upgradable)) - - la = file('/proc/loadavg').read() - load = la.split()[0] - if float(load) > 0.2: - out.append('L %s' % load) - - vol = self.volume() - if vol: - out.append('V %s' % vol) - - bat = self.battery_level() - if bat: - out.append('B %s%%' % bat) - - cap_state = self.battery_capacity_state() - if cap_state != 'ok': - out.append(color('green', cap)) - - out.append(time.strftime('%b %e %l:%M%P')) - - print ' '.join(out) - sys.stdout.flush() - - try: - pid, status = os.waitpid(0, os.WNOHANG) - self.pids.remove(pid) - except (OSError, KeyError): - pass - - return True - - @dbus.service.method('org.woozle.Status', - in_signature='s') - def notice(self, msg): - self.update(msg) - - @dbus.service.method('org.woozle.Status', - in_signature='') - def restart(self): - re_exec() - - @dbus.service.method('org.woozle.Status', - in_signature='b') - def set_debug(self, debug): - self.debug = debug - - def debcheck(self): - # I used to do this in a thread. Unfortunately, this expensive - # operation kept the entire apt cache around in RAM forever, - # making the status program the biggest memory user on my entire - # machine. That offends my sense of aesthetics, so now we fork - # and read from a pipe. - def cb(source, cb_condition): - s = source.recv(8192) - self.upgradable = int(s) - return False - - a,b = socket.socketpair() - if os.fork(): - gobject.io_add_watch(a, gobject.IO_IN, cb) - else: - l = [p for p in apt.Cache() if p.isUpgradable] - b.send(str(len(l))) - sys.exit(0) - return True - - def start(self): - self.update() - gobject.timeout_add(12 * 1000, self.update) - if apt: - self.debcheck() - gobject.timeout_add(900 * 1000, self.debcheck) - - -def re_exec(*ign): - os.execv(sys.argv[0], sys.argv) - - -def main(): - import signal - import gobject - import dbus.mainloop.glib - - # Set up main loop - dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) - - # kill -HUP makes this re-exec itself - signal.signal(signal.SIGHUP, re_exec) - - # Register ourselves as a service - session_bus = dbus.SessionBus() - dbus_name = dbus.service.BusName('org.woozle.Status', - session_bus) - - # Our founder - s = Status(session_bus, '/org/woozle/Status') - - # Go! - loop = gobject.MainLoop() - s.start() - loop.run() - - -if __name__ == '__main__': - main() diff --git a/src/python/watch.py b/src/python/watch.py deleted file mode 100755 index 3801189..0000000 --- a/src/python/watch.py +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/python - -"""watch.py -- Web site change notification tool -Author: Neale Pickett -Time-stamp: <2007-09-19 15:00:43 neale> - -Usage: urlwatch [-c|--config WATCHRC] - -This is something you can run from a cron job to notify you of changes -to a web site. You just set up a ~/.watchrc file, and run watcher.py -from cron. It mails you when a page has changed. - -I use this to check for new software releases on sites that just change -web pages; my wife uses it to check pages for classes she's in. - -You'll want a ~/.watchrc that looks something like this: - - to: your.email.address@example.com - http://www.example.com/path/to/some/page.html - -The 'to:' line tells watch.py where to send change notification email. -You can also specify 'from:' for an address the message should come from -(defaults to whatever to: is), and 'host:' for what SMTP server to send -the message through (defaults to localhost). - -When watch.py checks a URL for the first time, it will send you a -message (so you know it's working) and write some funny characters after -the URL in the .watchrc file. This is normal--watch.py uses these -characters to remember what the page looked like the last time it -checked. - -""" - -import os -import urllib2 as urllib -import sha -import smtplib -import sys - -host = 'localhost' -fromaddr = None -toaddr = None - -rc = os.path.expanduser('~/.watchrc') - -def usage(errmsg=None): - if errmsg: - print "error: %s" % errmsg - print - - print globals()['__doc__'] - - if errmsg: - sys.exit(1) - sys.exit(0) - -def myhash(data): - return sha.new(data).hexdigest() - -def notify(fromaddr, toaddr, url): - msg = """From: URL Watcher <%(from)s> -To: %(to)s -Subject: %(url)s changed - -%(url)s has changed! -""" % {'from': fromaddr, - 'to': toaddr, - 'url': url} - s = smtplib.SMTP(host) - s.sendmail(fromaddr, [toaddr], msg) - s.quit() - -def watch(rcfile): - global host, fromaddr, toaddr - - f = open(rcfile) - outlines = [] - for line in f.xreadlines(): - if line[0] == '#': - continue - - line = line.strip() - if not line: - continue - - splits = line.split(' ', 1) - url = splits[0] - if url == 'from:': - fromaddr = splits[1] - elif url == 'to:': - toaddr = splits[1] - if not fromaddr: - fromaddr = toaddr - elif url == 'mailhost:': - host = splits[1] - else: - if (not fromaddr) or (not toaddr): - raise ValueError("must set to: before any urls") - page = urllib.urlopen(url).read() - ph = myhash(page) - - try: - h = splits[1] - except IndexError: - h = None - if h != ph: - notify(fromaddr, toaddr, url) - line = '%s %s' % (url, ph) - outlines.append(line) - - f.close() - - f = open(rcfile, 'w') - f.write('\n'.join(outlines) + '\n') - f.close() - -if __name__ == '__main__': - import getopt - import sys - - opts, args = getopt.getopt(sys.argv[1:], 'c:h', ['config=', 'help']) - for k,v in opts: - if k in ('-c', '--config'): - rc = v - elif k in ('-h', '--help'): - usage() - else: - usage("Unknown option: %s" % k) - - watch(rc) diff --git a/src/xss.md b/src/xss.md deleted file mode 100644 index f59f8d9..0000000 --- a/src/xss.md +++ /dev/null @@ -1,107 +0,0 @@ -Title: xss: X Screensaver Construction Kit -Author: Neale Pickett - -[xss](http://woozle.org/neale/g.cgi/x11/xss) is a suite of X screensaver -utilities. You can use shell scripts to glue the tools together to -build your own screen saver and/or locker. You can use any -`xscreensaver` hack instead of the built-in `magic` hack, or you can use -`xlock` if you prefer. - - -The programs ------------- - -`xss` uses the decades-old MIT-SCREEN-SAVER extension to launch a -program when the X server turns on the built-in screen saver. Unlike -`xautolock`, `xss` blocks until the X server says it's time to do -something. - -`xsswin` makes a full-screen black window and runs some other program, -passing along the window ID in the environment (`$XSS_WINDOW`) and -possibly as an argument (`XSS_WINDOW` in argv is replaced with the ID). - -`xkeygrab` grabs the keyboard and mouse, and echoes all typed lines to -stdout. - -`xcursorpos` prints out the x and y coordinates of the cursor. - -`xbell` sounds the X server's bell. - -`magic` is a reimplementation of the "magic" screen saver from After -Dark. It might look weird at 8bpp. - - -Examples --------- - -Tell the X server to launch the screen saver after 90 seconds idle: - - $ xset s 90 - -Run like `xautolock`: - - $ xss xlock -mode qix & - -Just run a screen saver, don't lock - - $ xss -w /usr/lib/xscreensaver/deco -window-id XSS_WINDOW & - -Launch a program called "screenlock" when you're idle: - - $ xss screenlock & - -An simple "screenlock" script: - - #! /bin/sh - - xsswin magic XSS_WINDOW & pid=$! - xkeygrab | (while read l; do [ "$l" != "secret" ] && break; done) - kill $pid - -A more complex "screenlock" script which locks the screen awaiting a -pass phrase with the right md5 checksum. After 4 seconds of being -locked, it pauses mpd (iff it was playing). When the screen is -unlocked, mpd is resumed (iff it was playing beforehand). The script -won't lock if the cursor's at the top of the screen. - - #! /bin/sh - - xcursorpos | (read x y; [ $y -lt 20 ]) && exit 0 - mpc | fgrep -q '[playing]' && playing=1 - xsswin magic XSS_WINDOW 2>/dev/null & xsswin=$! - (sleep 4; [ $playing ] && kill -0 $xsswin 2>/dev/null && mpc --no-status pause) & - xkeygrab | ( - while read l; do - md5s=$(echo -n $l | md5sum | cut -d\ -f1) - if [ $md5s = 'a37c87558d98e9fe0484e09070268be1' ]; then - break - fi - xbell - done - ) - kill $xsswin - [ $playing ] && mpc --no-status play - - -Download --------- - -You can [browse the source](http://woozle.org/neale/g.cgi/x11/xss), -download a [tarball of the latest -commit](http://woozle.org/neale/g.cgi/x11/xss/snapshot/xss-master.tar.gz), or clone the -git repository: - - git clone http://woozle.org/~neale/projects/x11/xss - - -History -------- - -AIX apparently had something also called `xss` which did almost exactly -what mine does, but with command-line options. `magic` is similar to -the `qix` hack from xscreensaver and xlock. I'm not aware of anything -else like the rest of the programs, which is why I wrote them. - -I lifted some code from `beforelight` from the X11 distribution, and -from `slock` from [suckless.org](http://suckless.org/). Both have a -BSD/X11-like license. diff --git a/trigger.cgi.go b/trigger.cgi.go deleted file mode 100644 index cac0b29..0000000 --- a/trigger.cgi.go +++ /dev/null @@ -1,112 +0,0 @@ -package main - -import ( - "fmt" - "github.com/coduno/netrc" - "github.com/jsgoecke/tesla" - "log" - "net/http" - "net/http/cgi" - "net/smtp" - "os" -) - -// These are not actually secrets, and get posted around various forums -const clientId = "81527cff06843c8634fdc09e8ac0abefb46ac849f38fe1e431c2ef2106796384" -const clientSec = "c7257eb71a564034f9419ee651c7d0e5f7aa6bfbd18bafb5c5c033b093bb2fa3" - -func Kersplode(section string, error string, w http.ResponseWriter) { - errtxt := fmt.Sprintf("%s: %s", section, error) - - http.Error(w, errtxt, 500) - - // Send an email - c, _ := smtp.Dial("localhost:25") - defer c.Close() - c.Mail("neale@woozle.org") - c.Rcpt("dartcatcher@gmail.com") - wc, _ := c.Data() - defer wc.Close() - fmt.Fprintln(wc, "From: IFTTT Trigger ") - fmt.Fprintln(wc, "To: Neale Pickett ") - fmt.Fprintln(wc, "Subject: IFTTT trigger error") - fmt.Fprintln(wc, "") - fmt.Fprintln(wc, "Hi, this is the IFTTT trigger at woozle.org.") - fmt.Fprintln(wc, "I'm sorry to say that something went wrong with a recent request.") - fmt.Fprintln(wc, "Here is the text of the error:") - fmt.Fprintln(wc, "") - fmt.Fprintln(wc, errtxt) -} - -type Handler struct { - cgi.Handler -} - -func getSecret(host string) netrc.Entry { - n, _ := netrc.Parse() - return n[host] -} - -func (h Handler) TriggerHvac(w http.ResponseWriter, r *http.Request) { - secret := getSecret("teslamotors.com") - auth := tesla.Auth{ - ClientID: clientId, - ClientSecret: clientSec, - Email: secret.Login, - Password: secret.Password, - } - cli, err := tesla.NewClient(&auth) - if err != nil { - Kersplode("tesla.NewClient", err.Error(), w); - return - } - - vehicles, err := cli.Vehicles() - if err != nil { - Kersplode("cli.Vehicles", err.Error(), w); - return - } - - vehicle := vehicles[0] - if _, err := vehicle.Wakeup(); err != nil { - Kersplode("vehicle.Wakeup", err.Error(), w); - return - } - for i := 0; i < 5; i += 1 { - err := vehicle.StartAirConditioning() - if err == nil { - break - } else if (i == 5) { - Kersplode("vehicle.StartAirConditioning", err.Error(), w); - return - } - } - http.Error(w, "OK", 200) -} - -func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - secret := getSecret("host:trigger.cgi") - if r.FormValue("auth") != secret.Password { - http.Error(w, "Invalid authtok", 401) - return - } - - switch trigger := r.FormValue("trigger"); trigger { - case "hvac": - h.TriggerHvac(w, r) - default: - http.Error(w, "Undefined trigger", 422) - return - } -} - -func main() { - log.SetOutput(os.Stdout) - log.SetFlags(0) - log.SetPrefix("Status: 500 CGI Go Boom\nContent-type: text/plain\n\nERROR: ") - os.Setenv("HOME", "/home/neale") // required by netrc library - h := Handler{} - if err := cgi.Serve(h); err != nil { - log.Fatal(err) - } -}