Photos, stylesheets, and fixups
|
@ -0,0 +1,226 @@
|
||||||
|
/*
|
||||||
|
* Global
|
||||||
|
*/
|
||||||
|
|
||||||
|
html {
|
||||||
|
color:#061208;
|
||||||
|
background:#bfb8a6;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background:#e1d8c9;
|
||||||
|
border: solid black 1px;
|
||||||
|
font-family: serif;
|
||||||
|
color: #000;
|
||||||
|
margin: 1em auto;
|
||||||
|
padding: 2px;
|
||||||
|
min-width: 20em;
|
||||||
|
max-width: 50em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
font-family: "MgOpen Moderna", sans-serif;
|
||||||
|
color: #c17f6f;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #2A70E0;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
a:visited {
|
||||||
|
color: #469;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: #bb3;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
background: silver;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notice {
|
||||||
|
background: yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
.figure {
|
||||||
|
float: right;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #eeeeee;
|
||||||
|
border: solid gray 2px;
|
||||||
|
padding: 4px;
|
||||||
|
margin: 5px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Header elements
|
||||||
|
*/
|
||||||
|
|
||||||
|
h1#head {
|
||||||
|
background:#5c5f80;
|
||||||
|
border: 1px solid black;
|
||||||
|
text-align: left;
|
||||||
|
padding: 0em 0px 1em 10px;
|
||||||
|
margin: 0em;
|
||||||
|
font: normal 2em "URW Gothic L" sans-serif;
|
||||||
|
letter-spacing: 0.33em;
|
||||||
|
}
|
||||||
|
#head a {
|
||||||
|
color: #ffe;
|
||||||
|
}
|
||||||
|
#head img {
|
||||||
|
float: right;
|
||||||
|
border: 2px solid black;
|
||||||
|
margin: 0px 30px 5px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Navigation menu
|
||||||
|
*
|
||||||
|
* IE6 doesn't understand CSS selectors. So we use the > selector to
|
||||||
|
* specify stuff IE6 shouldn't see. This has the effect of permanently
|
||||||
|
* hiding the pop-up menus.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#nav {
|
||||||
|
position: absolute;
|
||||||
|
top: 4em;
|
||||||
|
|
||||||
|
text-align: left;
|
||||||
|
padding: 0em 1em;
|
||||||
|
margin: 0px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav li {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
#nav li a {
|
||||||
|
background: #bdcde4;
|
||||||
|
color: #5c5f80;
|
||||||
|
padding: 1px 10px;
|
||||||
|
}
|
||||||
|
#nav li a:hover {
|
||||||
|
color: yellow;
|
||||||
|
}
|
||||||
|
#nav li ul {
|
||||||
|
background:#bdcde4;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
#nav > li ul li {
|
||||||
|
display: list-item;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
#nav > li:hover {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
#nav > li:hover ul {
|
||||||
|
color: white;
|
||||||
|
text-align: left;
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 1.2em;
|
||||||
|
left: 0px;
|
||||||
|
margin: 0px 0px;
|
||||||
|
padding: 5px 5px;
|
||||||
|
min-width: 10em;
|
||||||
|
list-style-type: square;
|
||||||
|
}
|
||||||
|
#nav > li ul li {
|
||||||
|
display: list-item;
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
#nav ul.this {
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Main body
|
||||||
|
*/
|
||||||
|
|
||||||
|
#body {
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
address {
|
||||||
|
background:#5c5f80;
|
||||||
|
color: #bdcde4;
|
||||||
|
border: 1px solid black;
|
||||||
|
margin: 0;
|
||||||
|
clear: both;
|
||||||
|
padding: 0.5em;
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
address a {
|
||||||
|
color: #ffe;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IkiWiki crap
|
||||||
|
*/
|
||||||
|
|
||||||
|
.actions {
|
||||||
|
font-size: 80%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 1px 5px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions ul {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions li {
|
||||||
|
display: inline;
|
||||||
|
padding: 2px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inlinepage {
|
||||||
|
border: solid black 1px;
|
||||||
|
margin: 1em 2em;
|
||||||
|
background: #eee;
|
||||||
|
padding: 0em 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inlinepage .header a {
|
||||||
|
font-size: 150%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Orange feed button. */
|
||||||
|
.feedbutton {
|
||||||
|
background: #f60;
|
||||||
|
color: white;
|
||||||
|
border: outset black 1px;
|
||||||
|
padding: 0px 0.5em 0px 0.5em;
|
||||||
|
font: bold 8pt sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feedbutton:hover {
|
||||||
|
background: #f90;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagedate {
|
||||||
|
color: #666;
|
||||||
|
font-size: 75%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.img {
|
||||||
|
float: right;
|
||||||
|
background-color: #eef;
|
||||||
|
border: solid #ccd;
|
||||||
|
border-width: 1px 1px 0px 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.img caption {
|
||||||
|
font-size: 80%;
|
||||||
|
caption-side: bottom;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #eef;
|
||||||
|
border: solid #ccd;
|
||||||
|
border-width: 0px 1px 1px 1px;
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
Two rules. One Bean. Five Hundred ways to Win.
|
||||||
|
================================================
|
||||||
|
|
||||||
|
The ultimate German game
|
||||||
|
By [Cheapass Games](http://cheapass.com/)
|
||||||
|
|
||||||
|
Rule 1: Do not think about the bean.
|
||||||
|
Rule 2: Do not bisect the bean.
|
||||||
|
|
||||||
|
You can win with the longest road, the shortest road, or the most medium
|
||||||
|
road; the most balanced herd; the fastest hay wain (fair days only); the
|
||||||
|
most gregarious senator, the most accurate clock, or the closest ratio
|
||||||
|
of tadpoles to frogs (inverted) during any rainy period. You can win by
|
||||||
|
controlling the most of two commodities, but not of three. Victory goes
|
||||||
|
to the fastest ship (laden), the fastest ship (unladen), or the two
|
||||||
|
ships (one of each color) with the highest combined speed. You can win
|
||||||
|
by digging the deepest mine; raising the fluffiest herd; or by finishing
|
||||||
|
first in last race, last in first race, or first and last in the most
|
||||||
|
races overall. You can win with the largest rank of followers at the
|
||||||
|
end of the Insurrection Phase, the friendliest chef, or the least
|
||||||
|
talkative ghost. If you are the first player to reach the top of the
|
||||||
|
building with both your blimbers, or if your climbers are the only ones
|
||||||
|
left on the building, you win. The holder of the "Eternal Darkness"
|
||||||
|
token at the end of any round (unliss that player is Grandmother) wins.
|
||||||
|
Control of Nlort, Quimper, and Nice for one month (excluding Cunnery
|
||||||
|
Phase and not including Midnight Madness); joint monopolies in Space
|
||||||
|
Gas, Brie, and Garbage; or the tallest pile of pigs are also conditions
|
||||||
|
of victory. (Pigs in excess of total brake strength are deducted from
|
||||||
|
tallest pile, obviously.) You can win by creating the table with the
|
||||||
|
most legs; the most central city; the most non-central city; the planet
|
||||||
|
with the highest gravity; or by collecting the largest variety of
|
||||||
|
grains. Swimming is good for you. Each day spent in prison without
|
||||||
|
escaping: deduct 16 Points. Failure to say "Hail to the King" when a
|
||||||
|
King is played: Deduct 4 Points. Highest annual fluctuation each round
|
||||||
|
in relative value of all (controlled) local currencies combined as
|
||||||
|
measured by the particular net present value equation given in the last
|
||||||
|
line of the top card of the discard pile, not counting Banking cards
|
||||||
|
(unless the King is on or within one space of your most populous
|
||||||
|
territory): score as value. You can win by accumulating the most rice;
|
||||||
|
taking the most tourists on the same bus; removing the last stone from
|
||||||
|
the "wheel of eternity" board; retiring more than three vampires during
|
||||||
|
the Carnival; taking the longest turn; earning the most points; or by
|
||||||
|
taking the most moves back. The player with the closest pre-game guess
|
||||||
|
to sum of car numbers in second and third place in all races combined
|
||||||
|
(without going over) earns 21 points. If a player has paid to "Ride the
|
||||||
|
Pony" at least once before the Investment Phase of the third banking
|
||||||
|
day, that player wins once for each card he has collected from each
|
||||||
|
deck. Woodsman's Festival Bonus: the player with the most unused
|
||||||
|
Sovereigns (i.e., unspent for at least three turns, track with counters)
|
||||||
|
earns 5 Points for each merchant at the fair selling soup, wine, goats,
|
||||||
|
or decorative hats, and a triple bonus if any of these items contain
|
||||||
|
elements from that player's most recent Market Visit (please do not
|
||||||
|
combine bonuses for multiple entries in the same section, and ignore
|
||||||
|
foyers and vestibules when calculating square feet). You can with with
|
||||||
|
the cleanest monkey, the smallest enzyme, the most absurd victory
|
||||||
|
conditions, or the most chutzpah. If there is a tie for most
|
||||||
|
simultaneous victories, the game gose to the player with the longest
|
||||||
|
hair. If there is a tie for longest hair, the game goes to the player
|
||||||
|
with the most cards in hand. If there is a tie for most cards in hand,
|
||||||
|
the game goes to the player with the moistest feet. If there is a tie
|
||||||
|
for moistest feet, you may wish to score again: you probably missed
|
||||||
|
something.
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
[[!meta title="The Dink (merf!)"]]
|
||||||
|
|
||||||
|
Aliases: Dingo, (The) Dink, El Pinto Grande, Mr. Merf
|
||||||
|
Battle cry: merf!
|
||||||
|
|
||||||
|
[[!img img_5058.jpg size="500x500"]]
|
||||||
|
|
||||||
|
The Dink is (we think) a cross between a Chihuahua and a Norwich Terrier. (A Chihuahua/Norwich Terrier mix, for all you Google searchers out there). He is mellow for a small dog, but can get nervous like a Chihuahua when he goes for rides in the car (we don't drive much and he's not used to it). He doesn't have any problem with the bike trailer, though:
|
||||||
|
|
||||||
|
[[!img img_5087.jpg size="500x500"]]
|
||||||
|
|
||||||
|
His paperwork at the shelter said he was 4 months old in April, which would mean he was born in December of 2003. But that's awfully close to Christmas, so the person surrendering him may have put down how long they had him, which would mean he was actually born in October, 2003.
|
||||||
|
|
||||||
|
When we got him he already knew "sit" and was mostly house-trained. He's very friendly toward people and other dogs. During his only encounter with a cat (so far) he was curious but not overly interested.
|
||||||
|
|
||||||
|
[[!img img_5108.jpg size="500x500"]]
|
||||||
|
|
After Width: | Height: | Size: 407 KiB |
After Width: | Height: | Size: 698 KiB |
After Width: | Height: | Size: 456 KiB |
|
@ -0,0 +1,16 @@
|
||||||
|
:< := 8< 8= #< #= ~ |
|
||||||
|
|
|
||||||
|
:< := 8< 8= #< ~ |
|
||||||
|
|
|
||||||
|
:< := 8< 8= |
|
||||||
|
<|
|
||||||
|
:< := 8< 8= #< #= |
|
||||||
|
* |
|
||||||
|
:< := 8< 8= #= ~ |
|
||||||
|
|
|
||||||
|
:< := 8< |
|
||||||
|
~ |
|
||||||
|
:< |
|
||||||
|
~ |
|
||||||
|
|
|
||||||
|
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
[[!meta title="Papers"]]
|
||||||
|
|
||||||
|
These are papers I have written. Most of them were written to explain a
|
||||||
|
concept to someone on woozle. Hopefully other people will find them
|
||||||
|
useful, too.
|
||||||
|
|
||||||
|
[[!map pages="papers/*" show="title"]]
|
|
@ -0,0 +1,51 @@
|
||||||
|
[[!meta title="How DNS Works"]]
|
||||||
|
|
||||||
|
When you request a URL like `http://goob.woozle.org/~neale/foo.html`,
|
||||||
|
the first thing your browser does is send out a DNS query on
|
||||||
|
"goob.woozle.org". Specifically, it asks for A records or CNAMEs. A
|
||||||
|
records contain the name->IP mapping, and CNAMEs are like aliases.
|
||||||
|
CNAMEs are a little out of vogue these days, so I'll focus on A records.
|
||||||
|
|
||||||
|
Your browser sends the query to your recursive DNS resolver (the
|
||||||
|
nameserver in /etc/resolv.conf). The resolver then pulls out the last
|
||||||
|
part of the hostname (the .org), and looks for the server that can
|
||||||
|
answer for the .org Top Level Domain (TLD). It does this by asking some
|
||||||
|
big central nameservers that are listed by IP in its configuration. One
|
||||||
|
of those big central nameservers will come back and say something like,
|
||||||
|
".org is served by 1.2.3.4". Then your recursive resolver goes off to
|
||||||
|
1.2.3.4 and asks it about "woozle.org". 1.2.3.4 will come back with
|
||||||
|
another IP, in this case 216.39.146.229. Finally, the resolver connects
|
||||||
|
to 216.39.146.229 and asks it about "goob.woozle.org". 216.39.146.229
|
||||||
|
will come back with an answer of 216.39.146.229 (since 216.39.146.229 is
|
||||||
|
what's listed as goob.woozle.org's IP address).
|
||||||
|
|
||||||
|
The reason the .org domain said to go to 216.39.146.229 is because
|
||||||
|
that's what I listed as the primary authoritative name server for the
|
||||||
|
"woozle.org" domain with my host registrar (pacificroot.com). A lot of
|
||||||
|
people use networksolutions.com as their host registrar. So on
|
||||||
|
216.39.146.229, I have an authoritative name server (nsd) that knows
|
||||||
|
about the woozle.org domain. Some other authoritative name servers are
|
||||||
|
tinydns and BIND (the Buggy Internet Name Daemon).
|
||||||
|
|
||||||
|
Your recursive resolver has now obtained the mapping from
|
||||||
|
"goob.woozle.org" to 216.39.146.229, so it returns that IP address to
|
||||||
|
your web browser. If you're running a caching resolver, then the next
|
||||||
|
time it's asked it won't bother querying the Internet again, it will
|
||||||
|
just tell you the same thing it told you last time. That can make things
|
||||||
|
a whole lot faster.
|
||||||
|
|
||||||
|
Then your browser makes a TCP connection to 216.39.146.229, on port 80
|
||||||
|
(the HTTP port). When it connects, it sends something like this:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
GET /~neale/foo.html
|
||||||
|
Host: goob.woozle.org
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
That's helpful, because I have a whole lot of hostnames all going to
|
||||||
|
216.39.146.229. The web server looks at the host header and pulls up
|
||||||
|
the appropriate page for that domain. My web server, thttpd, has an
|
||||||
|
easy go of this: it just goes into a directory called "goob.woozle.org".
|
||||||
|
Apache and other servers take a little more configuration, but in
|
||||||
|
practice aren't much more difficult to run. This concept of many names
|
||||||
|
pointing to the same IP address is called "virtual hosting".
|
|
@ -0,0 +1,299 @@
|
||||||
|
[[!meta title="Debian on Digimatrix"]]
|
||||||
|
|
||||||
|
<p class="notice">
|
||||||
|
Caution: this is what I was running in 2004. Nowadays we just use
|
||||||
|
MythTV. Some of this stuff (like the X configuration) still applies,
|
||||||
|
though, which is why I'm leaving the page up.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
------------
|
||||||
|
|
||||||
|
We have a Digimatrix hooked up to our high-definition television. We
|
||||||
|
use it for a number of things:
|
||||||
|
|
||||||
|
* Watching DVDs
|
||||||
|
* Playing music from OGG and MP3 files
|
||||||
|
* Recording and playing back television shows
|
||||||
|
* Storing pictures and movies from our digital camera
|
||||||
|
* Hosting our pictures and movies, along with those of our friends,
|
||||||
|
on a web server
|
||||||
|
* Playing Super Nintendo video games
|
||||||
|
* Occasional desktop tasks
|
||||||
|
|
||||||
|
MythTV and Freevo vs. KDE
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
This sounds like a MythTV box, right? I tried MythTV, and Freevo, and
|
||||||
|
while I was impressed with how pretty they were, I just couldn't get
|
||||||
|
them working quite right.
|
||||||
|
|
||||||
|
[MythTV](http://www.mythtv.org/) gave a blank screen trying to watch or
|
||||||
|
record TV, with no useful error messages, and try as I might I just
|
||||||
|
couldn't figure out what the problem was. After spending three days on
|
||||||
|
it I gave up.
|
||||||
|
|
||||||
|
[Freevo](http://freevo.sourceforge.net/) had its own problems; I don't
|
||||||
|
remember exactly what they were now. I do remember feeling like Freevo
|
||||||
|
was held together with bailing wire and chewing gum, while MythTV had a
|
||||||
|
much more polished and easy-to-use feel to it.
|
||||||
|
|
||||||
|
Neither of them worked well out of the box with the Digimatrix remote
|
||||||
|
control.
|
||||||
|
|
||||||
|
In the end, I decided it'd be easier for everybody if we just used KDE.
|
||||||
|
It lets me bind actions to the key sequences the remote control sends
|
||||||
|
out, and for most TV-type activities the remote does enough to move
|
||||||
|
around in [Xine](http://xinehq.de/) and
|
||||||
|
[Konqueror](http://www.konqueror.org/). The
|
||||||
|
[x2x](http://x2x.dottedmag.net/) program allows us to use our laptops to
|
||||||
|
control things over the wireless network, when the remote doesn't
|
||||||
|
suffice. The Unix `at` utility and a little shell script lets us
|
||||||
|
schedule TV recordings with more ease than a VCR.
|
||||||
|
|
||||||
|
Best of all, there's no meta-information filed away in some obscure
|
||||||
|
database layout. Everything is a file somewhere and can be manipulated
|
||||||
|
with Konqueror or the shell.
|
||||||
|
|
||||||
|
This turns out to be a very workable setup.
|
||||||
|
|
||||||
|
|
||||||
|
h2. Installing the base system
|
||||||
|
|
||||||
|
I had to install the testing (etch) installation CD for it to have a
|
||||||
|
driver for the SiS 900 10/100 network card. Installation went smoothly
|
||||||
|
enough. Everything is detected at boot time except:
|
||||||
|
|
||||||
|
* LED Panel and front panel buttons (including volume)
|
||||||
|
* Infrared reciever
|
||||||
|
* 802.11b card ([Ralink rt2400 chipset](http://rt2x00.serialmonkey.com/)).
|
||||||
|
While I've gotten the rt2400 drivers to work, the card won't seem to
|
||||||
|
associate with my WAP until some other device does it first. This is
|
||||||
|
so inconvenient that I've run a long CAT-5 cable under the house so I
|
||||||
|
can use the 10/100 ethernet port.
|
||||||
|
|
||||||
|
|
||||||
|
I installed the following additional packages to help me administer the
|
||||||
|
machine:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
# aptitude install less zile screen ssh strace sudo ntp ntpdate
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
Web server
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Waldorf needed to run a web server to host photo albums.
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
# aptitude install mathopd stunnel4 php4-cgi rssh
|
||||||
|
# aptitude install netpbm jhead exiftran libjpeg-mmx-progs libjpeg-progs
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
I won't detail my web server configuration here, since that's unique to me.
|
||||||
|
|
||||||
|
X
|
||||||
|
----
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
# aptitude install x-window-system
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
To my surprise this brought in x.org. I run an HDTV over DVI, so to get
|
||||||
|
full screen, I had to change the configuration as follows:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
Section "Device"
|
||||||
|
Identifier "Generic Video Card"
|
||||||
|
Driver "sis"
|
||||||
|
Option "ForceCRT1Type" "DVI-D"
|
||||||
|
EndSection
|
||||||
|
|
||||||
|
Section "Monitor"
|
||||||
|
Identifier "Generic Monitor"
|
||||||
|
Option "DPMS"
|
||||||
|
HorizSync 30-65
|
||||||
|
VertRefresh 30-60
|
||||||
|
ModeLine "720p" 74.160 1280 1352 1392 1648 697 725 730 750
|
||||||
|
EndSection
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
I also had to add "720p" to the `Modes` of the `Display` subsection of
|
||||||
|
`Screen`.
|
||||||
|
|
||||||
|
You may notice I only have 697 pixels vertically. That's because my TV
|
||||||
|
puts about 23 lines in the "overscan", preventing me from seeing my KDE
|
||||||
|
toolbar. I haven't yet found a way to recenter the screen, this just
|
||||||
|
chops off the bottom. As a hack, I put empty KDE toolbars on the top,
|
||||||
|
left, and right borders. This keeps windows inside the viewable area.
|
||||||
|
|
||||||
|
|
||||||
|
h2. KDE
|
||||||
|
|
||||||
|
I like KDE. I've tried MythTV and Freevo and found it's just easier to
|
||||||
|
run KDE and occasionally use a mouse and keyboard. The only thing we
|
||||||
|
don't get is a snazzy interface to recording TV shows, but we don't tend
|
||||||
|
to want to do that very often. I may work on a web interface to XML-TV
|
||||||
|
listings later on.
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
# aptitude install kde kdm
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
I don't know if this is typical or not, but Debian's KDE went on without
|
||||||
|
asking me a single question. Kudos to the packagers.
|
||||||
|
|
||||||
|
|
||||||
|
h2. Sound
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
# aptitude install alsa-base alsa-utils
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
We use the Digimatrix's S/PDIF output (isn't it lame that it comes out
|
||||||
|
the front?). I know from a previous installation that if you just use
|
||||||
|
the defaults, you need to reboot between playing 2-channel audio and
|
||||||
|
using Xine's pass-through option to play a 7.1-channel DVD. I'm sure it
|
||||||
|
has something to do with the sound card resetting something or other.
|
||||||
|
The solution seems to be having ALSA multiplex audio, and while I don't
|
||||||
|
get why this works, work it does.
|
||||||
|
|
||||||
|
I put the following into `/etc/asound.conf`:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
pcm.asus-hw {
|
||||||
|
type hw
|
||||||
|
card 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pcm.!default {
|
||||||
|
type plug
|
||||||
|
slave.pcm "asus"
|
||||||
|
}
|
||||||
|
|
||||||
|
pcm.asus {
|
||||||
|
type dmix
|
||||||
|
ipc_key 1234
|
||||||
|
slave {
|
||||||
|
pcm "hw:0,0"
|
||||||
|
period_time 0
|
||||||
|
period_size 1024
|
||||||
|
buffer_size 4096
|
||||||
|
rate 48000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctl.asus-hw {
|
||||||
|
type hw
|
||||||
|
card 0
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
h2. A decent desktop
|
||||||
|
|
||||||
|
At this point I was able to browse the web and play music using KDE's
|
||||||
|
"JuK":http://developer.kde.org/~wheeler/juk.html, so I took a break to
|
||||||
|
dance around the living room with my 1-year-old daughter as ABBA sang to
|
||||||
|
us.
|
||||||
|
|
||||||
|
|
||||||
|
h2. Playing DVDs
|
||||||
|
|
||||||
|
I like kaffeine, mostly because it's part of KDE and I'm a purist. It
|
||||||
|
can play all sorts of movies and even has a nice startup screen that
|
||||||
|
allows you to type in numbers for various actions (play from playlist,
|
||||||
|
play DVD, etc.).
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
# aptitude install kaffeine
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
### DVD's Content Scrambling System ###
|
||||||
|
|
||||||
|
For some reason the DVD guys thought putting an encryption scheme on the
|
||||||
|
DVD was going to slow down piracy. I don't see any evidence of that
|
||||||
|
happening, but because of stupid laws in the US, you have to install
|
||||||
|
illegal software (as in, illegal to own) in order to watch the DVDs
|
||||||
|
you've bought or rented. To become a criminal, just run the following
|
||||||
|
commands:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
# wget http://www.dtek.chalmers.se/groups/dvd/deb/libdvdcss2_1.2.5-1_i386.deb
|
||||||
|
# dpkg -i libdvdcss2_1.2.5-1_i386.deb
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
The version and/or URL may have changed since I wrote this. Apologies
|
||||||
|
in advance.
|
||||||
|
|
||||||
|
|
||||||
|
### DVD drive speed ###
|
||||||
|
|
||||||
|
Linux does not use DMA on IDE devices when it boots up, you have to turn
|
||||||
|
that on yourself. I'm not sure what the reason is for this, probably
|
||||||
|
compatibility with some ancient thing that blows up if you attempt DMA.
|
||||||
|
In any case, turning on DMA will allows your DVD drive to keep up with
|
||||||
|
the data on the DVD.
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
# aptitude install hdparm
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
To turn on DMA, I put the following at the end of `/etc/hdparm.conf`.
|
||||||
|
While I was at it, I turned ot DMA for the hard drive too.
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
/dev/dvd {
|
||||||
|
dma = on
|
||||||
|
}
|
||||||
|
|
||||||
|
/dev/hda {
|
||||||
|
dma = on
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
### Try a DVD ###
|
||||||
|
|
||||||
|
At this point I was able to watch DVDs, so I did. I watched the first
|
||||||
|
DVD of the first season of Buffy, which turned out to be a terrible idea
|
||||||
|
since it's pretty dark and not very high quality. I played around with
|
||||||
|
the gamma settings in the KDE configuration tool, and set my gamma at
|
||||||
|
1.25. Then I adjusted the brightness, contrast, and saturation of
|
||||||
|
Kaffeine, and got what I think is a pretty nice-looking configuration.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
h2. The remote control
|
||||||
|
|
||||||
|
What good is a home theater system if you have to get up off your butt
|
||||||
|
to press buttons? This is America, man! I want to be able to eat
|
||||||
|
cheez-doodles and watch porn all night without having my feet hit the
|
||||||
|
floor, ever.
|
||||||
|
|
||||||
|
### The keyboard thingy ###
|
||||||
|
|
||||||
|
My Digimatrix came with this IR receiver thingy that goes in between the
|
||||||
|
keyboard and the keyboard port on the Digimatrix. It synthesizes
|
||||||
|
keypresses in response to your remote. Pretty slick! This is good
|
||||||
|
enough for most things, and for a long time I just bound remote
|
||||||
|
keystrokes to do certain things in KDE applications, and to certain
|
||||||
|
actions in Xine.
|
||||||
|
|
||||||
|
### lirc ###
|
||||||
|
|
||||||
|
lirc is the Linux Infra-Red Control system. It provides a standard
|
||||||
|
interface to various IR recievers and remote controls, and supplies
|
||||||
|
events to whatever wants to listen to it. KDE has a module to listen to
|
||||||
|
it, so I figured I'd give it a go.
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
# aptitude install kdelirc
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
Unfortunately, lirc 0.7 (the version in debian testing and unstable)
|
||||||
|
does not compile on Linux 2.6.12 and newer, so I had to install from
|
||||||
|
source code.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
[[!meta title="The 3-minute HTML tutorial"]]
|
||||||
|
|
||||||
|
<p>As computer formats go, HTML is really easy and logical. It's all just
|
||||||
|
text that you can edit with any basic text editor, like gedit nder
|
||||||
|
Gnome, or notepad in Windows. Let's start out with an example. Say you
|
||||||
|
have a sentence, and you want one word in it to be bold. That sentence
|
||||||
|
would look like this:</p>
|
||||||
|
|
||||||
|
<pre>Guess which word is <b>bold</b>?</pre>
|
||||||
|
|
||||||
|
<p>As should be obvious, the bold word in that sentence is "word". Just
|
||||||
|
kidding, it's the word "bold", in between <code><b></code> and <code></b></code> tags.
|
||||||
|
The sentence will show up like so:</p>
|
||||||
|
|
||||||
|
<blockquote>Guess which word is <b>bold</b>?</blockquote>
|
||||||
|
|
||||||
|
<p>You now know HTML, the rest is just learning the names of the tags.</p>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<p>Seriously! Here's a slightly larger example:</p>
|
||||||
|
|
||||||
|
<pre><title>My first web page</title>
|
||||||
|
<h1>Welcome</h1>
|
||||||
|
<p>
|
||||||
|
Welcome to my <b>first ever</b> web page!
|
||||||
|
It features:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>A title!</li>
|
||||||
|
<li>A header!</li>
|
||||||
|
<li>A paragraph!</li>
|
||||||
|
<li>An unordered list!</li>
|
||||||
|
</ul>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>So what you end up with in the end is something like this:</p>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
<div style="background: #ddd; border: solid black 3px;">
|
||||||
|
<div style="background: #00A; color: white; width: 100%;">
|
||||||
|
My first web page - WoozWeb Browser
|
||||||
|
</div>
|
||||||
|
<h1 style="text-align: left;">Welcome</h1>
|
||||||
|
<p>
|
||||||
|
Welcome to my <b>first ever</b> web page!
|
||||||
|
It features:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>A title!</li>
|
||||||
|
<li>A header!</li>
|
||||||
|
<li>A paragraph!</li>
|
||||||
|
<li>An unordered list!</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
<p>The part inside the <code><title></code> and the <code></title></code> is the title of your
|
||||||
|
page; that's what goes in the window frame at the very top of your web
|
||||||
|
browser window, above the menus and everything else.</p>
|
||||||
|
|
||||||
|
<p>The stuff in between <code><h1></code> and <code></h1></code> is a "level-1 header". That
|
||||||
|
means that it's the biggest header you can get. There are also h2, h3,
|
||||||
|
h4, h5, and h6 headers, with h6 being the smallest.</p>
|
||||||
|
|
||||||
|
<p>The stuff inside <code><p></code> and <code></p></code> is a paragraph. Since HTML treats
|
||||||
|
spaces the same as line breaks, you need to use paragraph tags around
|
||||||
|
each paragraph. Inside the example paragraph is our old friend bold.</p>
|
||||||
|
|
||||||
|
<p>Then, there's <code><ul></code> and <code></ul></code>, an "unordered list" (as opposed to an
|
||||||
|
ordered list, which would have a number by each item). Inside the list
|
||||||
|
are four "list items", enclosed in <code><li></code> and <code></li></code>.</p>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<p>Now check this action out:</p>
|
||||||
|
|
||||||
|
<pre><p>
|
||||||
|
This is an
|
||||||
|
<img src="http://www.woozle.org/images/star.png"
|
||||||
|
alt="star"></img> image, and
|
||||||
|
<a href="http://woozle.org/">this</a> is a link.
|
||||||
|
</p>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>Which will show up like this:</p>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
<p>This is an <img src="http://www.woozle.org/images/star.png" alt="star"> image, and <a href="http://woozle.org/">this</a> is a link.
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
<p>The example above has an image tag, with two "attributes", "src" and
|
||||||
|
"alt". The "src" attribute in an <code><img></code> tag gives the
|
||||||
|
URL to a picture, and the "alt" attribute is the text that's displayed
|
||||||
|
to people who can't see images (blind users, folks without graphics
|
||||||
|
capabilities, or if there's a problem on your web server). The "alt"
|
||||||
|
attribue is required, but you can set it to <code>""</code> if there's
|
||||||
|
nothing appropriate for alternate text.</p>
|
||||||
|
|
||||||
|
<p>Lastly, the infamous link, enclosed inside of <code><a></code>
|
||||||
|
and <code></a></code>. The "href" attribute gives the URL that
|
||||||
|
the browser will go to if you click the link.</p>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<p>That's it for basic HTML, and it should be enough to get you started
|
||||||
|
writing your own pages. So go write something! The best way to learn
|
||||||
|
it is to try stuff out and see what it does. For more neat HTML tags,
|
||||||
|
check out <a href="http://www.cs.tut.fi/~jkorpela/HTML3.2/">HTML 3.2 by
|
||||||
|
Examples</a>, which is what I used to learn HTML.</p>
|
|
@ -0,0 +1,170 @@
|
||||||
|
[[!meta title="“Reply-To” Munging Still Considered Harmful. Really."]]
|
||||||
|
|
||||||
|
An Earnest Plea to People Still Having This Debate
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
A long time ago, Chip Rosenthal wrote a fine document entitled
|
||||||
|
['Reply-To' Munging Considered
|
||||||
|
Harmful](http://www.unicom.com/pw/reply-to-harmful.html). It details the
|
||||||
|
problems caused by `Reply-To` munging. Chip's essay basically points
|
||||||
|
out that:
|
||||||
|
|
||||||
|
* Munging only helps people with broken mail clients.
|
||||||
|
* Munging can catch people by surprise, since in every other email
|
||||||
|
they've gotten with multiple recipients, when they hit "reply" it goes
|
||||||
|
only to the sender.
|
||||||
|
* Munging totally breaks things for people who want replies to go to a
|
||||||
|
different address than the one they sent the mail from.
|
||||||
|
|
||||||
|
|
||||||
|
In 2000 (or maybe earlier), Simon Hill wrote a response called [Reply-To
|
||||||
|
Munging Considered
|
||||||
|
Useful](http://www.metasystema.net/essays/reply-to.mhtml), which is
|
||||||
|
frequently offered as a rebuttal to Chip's document in online debates.
|
||||||
|
Simon's response boils down to the following:
|
||||||
|
|
||||||
|
* Munging encourages list discussion.
|
||||||
|
* RFC 822 seems to indicate it's okay.
|
||||||
|
* Munging makes things easier on broken mail clients.
|
||||||
|
|
||||||
|
|
||||||
|
People still using these two documents to debate the issue are wasting
|
||||||
|
everybody's time. The issue was definitively settled in 2001, and Chip
|
||||||
|
won.
|
||||||
|
|
||||||
|
|
||||||
|
The IETF settles things
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
The IETF (Internet Engineering Task Force) writes the standards
|
||||||
|
documents for the Internet. Such a document, called an RFC (Request For
|
||||||
|
Comments), attempts to unambiguously lay out in English the way things
|
||||||
|
are supposed to take place. They are deliberated intensely, sometimes
|
||||||
|
for years, and every paragraph is scrutinized by scores of experts.
|
||||||
|
Still, problems do crop up with RFCs over time, be they from
|
||||||
|
ambiguities, new technologies, or flat out mistakes. If problems are
|
||||||
|
big enough or numerous enough, the IETF will issue a new RFC to correct
|
||||||
|
the deficiencies of an older one. This new document is said to
|
||||||
|
_obsolete_ the old one.
|
||||||
|
|
||||||
|
Both Chip's and Simon's documents refer to RFC 822, "Standard For The
|
||||||
|
Format Of ARPA Internet Text Messages", issued way back in 1982, before
|
||||||
|
most of us even knew what a computer network was. Indeed, RFC 822
|
||||||
|
doesn't say anything about whether or not mailing lists can or should
|
||||||
|
set the `Reply-To` header field. Chip interpreted it one way, and Simon
|
||||||
|
another.
|
||||||
|
|
||||||
|
In April of 2001, the IETF issued af new document, [RFC
|
||||||
|
2822](http://www.ietf.org/rfc/rfc2822.txt), which obsoletes RFC 822. In
|
||||||
|
this new RFC, the author addresses the `Reply-To` header field in a few
|
||||||
|
places, but the most relevant to this discussion is the following in
|
||||||
|
section 3.6.2 "Originator fields":
|
||||||
|
|
||||||
|
> When the "Reply-To:" field is present, it indicates the mailbox(es) to
|
||||||
|
> which the author of the message suggests that replies be sent.
|
||||||
|
|
||||||
|
Your list software is not "the author of the message", so it must not
|
||||||
|
set or in any way meddle with the `Reply-To` header field. That field
|
||||||
|
exists for the author and the author alone. If your list munges it, you
|
||||||
|
are violating the standard.
|
||||||
|
|
||||||
|
These standards are not written flippantly, they are carefully crafted
|
||||||
|
in such a way as to ensure everything on the Internet works as smoothly
|
||||||
|
as possible. So do the Internet a favor and leave `Reply-To` alone.
|
||||||
|
|
||||||
|
|
||||||
|
How to specify where to post list messages
|
||||||
|
------------------------------------------
|
||||||
|
|
||||||
|
[RFC 2369](http://www.ietf.org/rfc/rfc2369.txt) specifies, in section
|
||||||
|
3.4, the `List-Post` header field:
|
||||||
|
|
||||||
|
> The List-Post field describes the method for posting to the list.
|
||||||
|
> This is typically the address of the list, but MAY be a moderator, or
|
||||||
|
> potentially some other form of submission. For the special case of a
|
||||||
|
> list that does not allow posting (e.g., an announcements list), the
|
||||||
|
> List-Post field may contain the special value "NO".
|
||||||
|
|
||||||
|
Modern mail list software sets this header field, or provides some
|
||||||
|
mechanism for the administrator to set it.
|
||||||
|
|
||||||
|
Mail clients are beginning to act on it too. The KMail program Simon
|
||||||
|
references uses the presence of this header field to make the "reply"
|
||||||
|
action send to the list and the list only, and provides a "reply to
|
||||||
|
author" action that will always send to the message's author whether
|
||||||
|
it's a list or not. "Reply to author" honors the `Reply-To` field.
|
||||||
|
This is exactly the convenient behavior Simon claims to want in his
|
||||||
|
essay, and it can all be done using standard behavior.
|
||||||
|
|
||||||
|
|
||||||
|
Getting two copies of the same email
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
Some people complain that they'll get two copies of the same email.
|
||||||
|
Since they're on the list, their first copy is the one sent to them by
|
||||||
|
the list. When the responder hit "reply all", it also put their email
|
||||||
|
address in the recipient list, so they get a second copy directly.
|
||||||
|
|
||||||
|
Fortunately, there's already a technical solution to this. Since all
|
||||||
|
mail clients put a unique `Message-ID` header field on their email, a
|
||||||
|
mail reader has only to compare the `Message-ID` of a message to
|
||||||
|
previously-recieved messages. If it's the same, then the second message
|
||||||
|
is a duplicate and can be safely ignored.
|
||||||
|
|
||||||
|
If your mail reader doesn't do this, that's too bad, but it's not an
|
||||||
|
excuse to violate Internet standards and surprise people with
|
||||||
|
inconsistent behavior, just to prevent you from having to delete a few
|
||||||
|
emails. Anyone who gets any spam at all knows how to delete email.
|
||||||
|
|
||||||
|
|
||||||
|
It's What People Want
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
I can't tell you how many `Reply-To` munging lists I've been on where
|
||||||
|
someone (or multiple people) send private messages to the list by
|
||||||
|
accident. "But I hit reply, not reply to all!" I've even been bitten
|
||||||
|
by this, right after a message to the list chiding people for sending
|
||||||
|
private messages to the list!
|
||||||
|
|
||||||
|
People want their mail client to be consistent. When they hit "reply"
|
||||||
|
they want it to go to the person who wrote the message. When they hit
|
||||||
|
"reply to all", they want it to also go to everyone who received it.
|
||||||
|
Most people understand this by now, since it's how their mail reader has
|
||||||
|
worked for every email they've ever gotten. Your list shouldn't be any
|
||||||
|
different.
|
||||||
|
|
||||||
|
Sure, mistakes are going to happen, maybe on your list, maybe with an
|
||||||
|
email with multiple recipients. It's not your job as a list owner to
|
||||||
|
make sure people can't make mistakes with their software. If the job
|
||||||
|
belongs to anybody other the user, it'd be the author of the mail
|
||||||
|
client. Your job is to make sure your mail list follows Internet
|
||||||
|
standards, and as a result works consistently for the user.
|
||||||
|
|
||||||
|
|
||||||
|
Summary
|
||||||
|
-------
|
||||||
|
|
||||||
|
Some people want to munge `Reply-To` header fields. They believe it
|
||||||
|
makes reply-to-list easier, and it encourages more list traffic. It
|
||||||
|
really does neither, and not only is it a poor idea but it's forbidden
|
||||||
|
by Internet standards.
|
||||||
|
|
||||||
|
The IETF has spoken, and if you violate their standard and munge your
|
||||||
|
`Reply-To` header fields you're just creating problems for everybody.
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
|
References
|
||||||
|
----------
|
||||||
|
|
||||||
|
* ['Reply-To' Munging Considered
|
||||||
|
Harmful](http://www.unicom.com/pw/reply-to-harmful.html)
|
||||||
|
* [Reply-To Munging Considered
|
||||||
|
Useful](http://www.metasystema.net/essays/reply-to.mhtml)
|
||||||
|
* [RFC 822](http://www.ietf.org/rfc/rfc822.txt): _STANDARD FOR THE FORMAT
|
||||||
|
OF ARPA INTERNET TEXT MESSAGES_
|
||||||
|
* [RFC 2822](http://www.ietf.org/rfc/rfc2822.txt): _Internet Message
|
||||||
|
Format_
|
||||||
|
* [RFC 2369](http://www.ietf.org/rfc/rfc2369.txt): _The Use of URLs as
|
||||||
|
Meta-Syntax for Core Mail List Commands and their Transport through
|
||||||
|
Message Header Fields_
|
|
@ -0,0 +1,132 @@
|
||||||
|
[[!meta title="Introduction To TCP Sockets"]]
|
||||||
|
|
||||||
|
Client Sockets
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Sockets are sort of like PBX phone systems, where the IP address is
|
||||||
|
the phone number, and the port is the extension. Every paired
|
||||||
|
(connected) socket has a source IP/port and a destination IP/port.
|
||||||
|
|
||||||
|
|
||||||
|
When you want to hook up to a listening server, first you have to
|
||||||
|
request a socket from the kernel. You use the socket() call. In
|
||||||
|
Python, that'd be:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
import socket
|
||||||
|
s = socket.socket(socket.PF_INET, socket.SOCK_STREAM)
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
That tells Python that you want a socket in the Internet class (as
|
||||||
|
opposed to, say Appletalk), and that it should be a streaming
|
||||||
|
socket (TCP, as opposed to a datagram socket, which would be UDP).
|
||||||
|
|
||||||
|
The next thing you can do is tell the kernel what IP/port you'd like to
|
||||||
|
use as the source port (think of this as the number that will show
|
||||||
|
up on caller ID when you make your connection). You can do this
|
||||||
|
with the bind() call, like this:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
s.bind(("192.168.4.216", 9234))
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
This tells the kernel to use the IP/port of 192.168.4.216 and 9234. When
|
||||||
|
you make an outbound connection, it will come from that IP and that
|
||||||
|
port. You can use 0 for the IP and 0 for the port, in which case
|
||||||
|
the kernel picks one for you. Or you can skip the bind call
|
||||||
|
entirely, which is the same as binding to `('', 0)`.
|
||||||
|
|
||||||
|
So you've got a socket and it's bound to something, now all you
|
||||||
|
have to do is connect it (make your phone call). In Python:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
s.connect(("192.168.4.12", 80))
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
That'll hook you up to port 80 (the HTTP port) of 192.168.4.12.
|
||||||
|
|
||||||
|
From then on you can use s just like it was a file, with read and
|
||||||
|
write replaced with send and recv (I think you can actually use
|
||||||
|
read and write on sockets, but traditionally send and recv are used):
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
s.send("GET / HTTP/1.0\n\n")
|
||||||
|
print s.recv(8192)
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
When you're done, just close it:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
s.close()
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
Server Sockets
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Since a server operates on a IP/port combination too, you still do the
|
||||||
|
socket and bind calls (and you can skip the bind if you want any random
|
||||||
|
port, but I've never heard of a server that doesn't care what port it's
|
||||||
|
listening to). Then the next thing you have to do for a server, instead
|
||||||
|
of connecting, is listen. In Python:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
s.listen()
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
That tells the kernel to start listening for incoming connections
|
||||||
|
to the IP/Port you got with bind.
|
||||||
|
|
||||||
|
Once you get a connection set up in the kernel, you have to ask the
|
||||||
|
kernel for that connection. That conenction will be a different file
|
||||||
|
descriptor than the one you had listening, so that you can have multiple
|
||||||
|
connections plugged in to the same ip/port and keep them all distinct.
|
||||||
|
The call you make to the kernel is "accept" and by default it will block
|
||||||
|
(that is, the kernel won't return control to your program) until there's
|
||||||
|
a new socket established. So you'll see loops like this:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
while 1:
|
||||||
|
c = s.accept()
|
||||||
|
cli_sock, cli_addr = c
|
||||||
|
|
||||||
|
cli_sock.send("Hello, person from %s" % cli_addr)
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
So there, you are accepting from s, it puts the new socket in c. Python
|
||||||
|
does a little trick here, in that it actually returns a tuple (like a
|
||||||
|
list) with the first value the actual socket, and the second value the
|
||||||
|
address (ip/port) of the incoming connection. So you don't have to ask
|
||||||
|
again to find out who just connected to you, get get it with the accept
|
||||||
|
call. The C library does this in a slightly different way, but you
|
||||||
|
still get the same information. And at that point, you can start
|
||||||
|
treating the client socket just like you would any other connected
|
||||||
|
socket.
|
||||||
|
|
||||||
|
|
||||||
|
Forking for fun and profit
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
The code above is the serializing (FIFO) model, but you'd need to
|
||||||
|
fork to handle multiple requests simultaneously. In practice,
|
||||||
|
hardly anything serializes requests, what's more common is
|
||||||
|
something like this:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
while 1:
|
||||||
|
c = s.accept()
|
||||||
|
if os.fork():
|
||||||
|
c.close()
|
||||||
|
else:
|
||||||
|
do_client_stuff(c)
|
||||||
|
c.close()
|
||||||
|
exit(0)
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
If you're just learning sockets, do a serialized socket first. It'll be
|
||||||
|
easier to understand what's going on that way. But forks are easy too.
|
||||||
|
You call fork() and then you get a new process that starts with the same
|
||||||
|
everything (all the variables are the same and it starts running right
|
||||||
|
after the fork() call). After the fork, both are running as if the fork
|
||||||
|
has just completed, but the parent's fork returned the PID of the new
|
||||||
|
process, and the child's fork returned 0.
|
|
@ -0,0 +1,7 @@
|
||||||
|
[[!meta title="Poems"]]
|
||||||
|
|
||||||
|
If wishes were horses
|
||||||
|
And poets were kings
|
||||||
|
I guess I'd still have my day job.
|
||||||
|
|
||||||
|
[[!map pages="poems/*" show="title"]]
|
|
@ -0,0 +1,25 @@
|
||||||
|
[[!meta title="Ode to the Bagel Girl"]]
|
||||||
|
|
||||||
|
We stand waiting for the 253 to Redmond
|
||||||
|
The fog sits lightly on our tongues
|
||||||
|
Cigarette smoke blending in
|
||||||
|
|
||||||
|
I walk to catch a glimpse of the bagel girl
|
||||||
|
(who works the second shift,
|
||||||
|
from noon to eight on weekdays).
|
||||||
|
|
||||||
|
Oh bagel girl, make me a cappucino.
|
||||||
|
Brew the espresso dark and heavy
|
||||||
|
Froth the milk thick and heady.
|
||||||
|
|
||||||
|
Tell me you love me, bagel girl.
|
||||||
|
Ride away with me
|
||||||
|
Into a cream cheese sunset.
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
I wrote this on the bus home. There was a young girl with a beautiful
|
||||||
|
face sitting at the front of the bus, and I kept looking at her before I
|
||||||
|
started to write. I was laughing so hard as I wrote this, that she
|
||||||
|
started to get pretty self-conscious.
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
[[!meta title="Double Dactyls"]]
|
||||||
|
|
||||||
|
Hoobimus Goobimus,
|
||||||
|
Emad El-Haraty
|
||||||
|
“Please call me Fishmael”
|
||||||
|
said to #tron.
|
||||||
|
|
||||||
|
But for the myriad
|
||||||
|
nicks in the channel list,
|
||||||
|
characteristically,
|
||||||
|
they were all gone.
|
|
@ -0,0 +1,21 @@
|
||||||
|
[[!meta title="Ducks"]]
|
||||||
|
|
||||||
|
If ducks ran the country, I'm sure you'll agree
|
||||||
|
Things sure would be different for you and for me!
|
||||||
|
For starters, we'd live near a pond or a lake
|
||||||
|
On your birthday, you'd have to eat fish, and not cake.
|
||||||
|
|
||||||
|
At lunchtime we'd all go eat grass under trees.
|
||||||
|
For snacks we'd have quackers, without any cheese.
|
||||||
|
We'd waddle around from point A to point B,
|
||||||
|
and when going in groups, we would all form a V.
|
||||||
|
|
||||||
|
We wouldn't wear raincoats in winter or fall,
|
||||||
|
But then, I suppose we'd wear nothing at all.
|
||||||
|
Every person on earth would be covered with down
|
||||||
|
And I bet that would make it much harder to drown.
|
||||||
|
|
||||||
|
If ducks ran the country, it sure would be strange.
|
||||||
|
And everything we find familiar would change.
|
||||||
|
I don't think I'd like it. No, not in the least.
|
||||||
|
But it still would be better than if it were geese.
|
|
@ -0,0 +1,8 @@
|
||||||
|
[[!meta title="My Goldfish Wish"]]
|
||||||
|
|
||||||
|
I wish a goldfish were my pet!
|
||||||
|
I'd make sure he was warm and wet.
|
||||||
|
I'd keep him in the kitchen sink,
|
||||||
|
And wash him when he starts to stink.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
[[!meta title="Poem For A Moonlit Lake With City Lights Reflecting"]]
|
||||||
|
|
||||||
|
It,
|
||||||
|
is getting,
|
||||||
|
dark.
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
Written while leaving dance class at Madrona Park; August 10, 9:07pm
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
[[!meta title="Ode to Mice"]]
|
||||||
|
|
||||||
|
Leave them mice alone
|
||||||
|
Let them wander through your home
|
||||||
|
Eat little holes into your walls
|
||||||
|
Let them scamper up and down the halls
|
||||||
|
|
||||||
|
Leave them mice alone
|
||||||
|
Let them grow up on their own
|
||||||
|
Give them places for mousey beds
|
||||||
|
Protect their little mousey heads
|
||||||
|
|
||||||
|
And sometimes late at night
|
||||||
|
When you and your boyfriend had a fight
|
||||||
|
Those little mouseys, they just might
|
||||||
|
Not give a damn
|
||||||
|
|
||||||
|
But when you curl up in bed by yourself
|
||||||
|
And you're hoping that somebody else
|
||||||
|
Can feel your anguish, up there on the shelf
|
||||||
|
They'll be eating SPAM
|
||||||
|
|
||||||
|
So leave them mice alone
|
||||||
|
Leave them lots of styrofoam
|
||||||
|
And sweaters, and pink insulation stuff
|
||||||
|
Make sure that they have enough
|
||||||
|
|
||||||
|
Leave them mice alone
|
||||||
|
Don't call the Orkin man on the phone
|
||||||
|
Those little mouseys
|
||||||
|
They are your friends
|
|
@ -0,0 +1,26 @@
|
||||||
|
[[!meta title="Optimized"]]
|
||||||
|
|
||||||
|
This poem made for Wooz-Web 8
|
||||||
|
So please download today.
|
||||||
|
On my computer, it looks great!
|
||||||
|
On yours, it might turn gray.
|
||||||
|
|
||||||
|
It uses ActivePoetry
|
||||||
|
(By WoozleSoft, v4.3)
|
||||||
|
And fonts from [here](#), and [here](#), and [here](#);
|
||||||
|
Without those fonts, it sucks, I fear.
|
||||||
|
|
||||||
|
You'll need a 3-D graphics chip
|
||||||
|
To see the verses do a flip;
|
||||||
|
A hundred gigabytes of RAM
|
||||||
|
(unless you want your mouse to jam)
|
||||||
|
|
||||||
|
Get MarcoMuddy SlickWave Bash
|
||||||
|
If you don't want the rhymes to crash
|
||||||
|
And please be sure to maximize
|
||||||
|
So that the meter can resize.
|
||||||
|
|
||||||
|
I'm sorry if you cannot see
|
||||||
|
This interactive poetry
|
||||||
|
But I just cannot take the time
|
||||||
|
To make my poems sound good on every browser!
|
|
@ -0,0 +1,44 @@
|
||||||
|
[[!meta title="The Poopy Song"]]
|
||||||
|
|
||||||
|
![G|:ccGG cc2c|ddAA d3c|BBBB BB2A|GGAB c3G:|](poopy-music.png)
|
||||||
|
|
||||||
|
I had a baby Ginnie
|
||||||
|
She liked to poop a lot
|
||||||
|
And when it came out of her butt
|
||||||
|
The temperature was hot
|
||||||
|
|
||||||
|
She liked to poop her diapers
|
||||||
|
The smell was never strong
|
||||||
|
And when she pooped them really good
|
||||||
|
Her dad would sing a song
|
||||||
|
|
||||||
|
### chorus ###
|
||||||
|
Poopy Poopy Poopy
|
||||||
|
Poopy all day long
|
||||||
|
Poopy Poopy Poopy
|
||||||
|
This is the Poopy song
|
||||||
|
(repeat)
|
||||||
|
|
||||||
|
This little baby pooper
|
||||||
|
She liked to bounce and dance
|
||||||
|
And when you least expected it
|
||||||
|
She’d up and poop her pants
|
||||||
|
|
||||||
|
She’d poopy in the morning
|
||||||
|
She’d poopy in the night
|
||||||
|
If she went long between her poops
|
||||||
|
You knew things weren’t right
|
||||||
|
|
||||||
|
[chorus]
|
||||||
|
|
||||||
|
Her poop was many colors
|
||||||
|
Like yellow, brown, and green
|
||||||
|
Sometimes she made so much of it
|
||||||
|
It made you want to scream
|
||||||
|
|
||||||
|
She always pooped for pleasure
|
||||||
|
She never pooped for spite
|
||||||
|
If poop were good and evil, then
|
||||||
|
She’d poop for what was right
|
||||||
|
|
||||||
|
[chorus]
|
|
@ -0,0 +1,21 @@
|
||||||
|
[[!meta title="Sap"]]
|
||||||
|
|
||||||
|
I love you dear, so very much
|
||||||
|
That I get sappy when we touch
|
||||||
|
Or even when I think of you
|
||||||
|
Your eyes so red, your hair so blue
|
||||||
|
|
||||||
|
I see your face, it warms my heart
|
||||||
|
It makes my colon leap, then fart
|
||||||
|
There aren't enough words to express how much I am in love with you
|
||||||
|
Even breaking meter won't do
|
||||||
|
|
||||||
|
The fleshy folds around your teeth
|
||||||
|
Are red like blood, beyond belief
|
||||||
|
They make me want to osculate
|
||||||
|
And doing so is super-great
|
||||||
|
|
||||||
|
In short, my love, you fill my gap
|
||||||
|
With sticky, drippy, sugary sap
|
||||||
|
I hope you're with me for all time
|
||||||
|
And that is why I wrote these lines
|
|
@ -0,0 +1,31 @@
|
||||||
|
[[!meta title="Snark Hair"]]
|
||||||
|
|
||||||
|
Has anyone ever turned into a snark?
|
||||||
|
In the sun? In the rain? When it's light? When it's dark?
|
||||||
|
I'm asking because in the past couple days
|
||||||
|
Snark features have turned up in frightening ways.
|
||||||
|
|
||||||
|
On Monday the snark hair began to appear
|
||||||
|
I felt just a tuft of it under my ear.
|
||||||
|
On Tuesday, my daugter declared with shagrin
|
||||||
|
It grew to envelop my cheeks and my chin.
|
||||||
|
|
||||||
|
On Wednesday I noted with mounting alarm
|
||||||
|
that snark hair was starting to grow on my arm.
|
||||||
|
On Thursday I woke up and got quite distressed:
|
||||||
|
the thick, furry snark hair had covered my chest!
|
||||||
|
|
||||||
|
This morning, I came in to work and found out
|
||||||
|
my nose was beginning to look like a snout.
|
||||||
|
My hands looked like snark claws; my feet did as well,
|
||||||
|
I carried a pungent, distinct snark-like smell.
|
||||||
|
|
||||||
|
It looks as though snarkdom may be in the works.
|
||||||
|
I'm still undecided about all the perks:
|
||||||
|
My hearing and sniffing's improved, and that's cool,
|
||||||
|
But everything's suddenly slimed with snark drool.
|
||||||
|
|
||||||
|
So if you're aware of a cure for this ill,
|
||||||
|
be it some kind of tonic, or potion, or pill,
|
||||||
|
please tell me! Or else when I go to the park,
|
||||||
|
kids won't call me "Mister", they'll just shout "Hey, Snark!"
|
|
@ -0,0 +1,6 @@
|
||||||
|
[[!meta title="Winders"]]
|
||||||
|
|
||||||
|
If I should ever find myself
|
||||||
|
A-washin' dirty winders,
|
||||||
|
I think that I'd confine myself
|
||||||
|
To washin' ol' Max Enders'.
|
|
@ -0,0 +1,19 @@
|
||||||
|
[[!meta title="32 lines about 16 lusers"]]
|
||||||
|
|
||||||
|
ian is a manager, he also rides a motorbike
|
||||||
|
hbunny's a boss-man too, and he pumps iron day and night
|
||||||
|
Meeko is a quasi-furry, lives in Georgia with the fam
|
||||||
|
Seattle City pays owreee to try and stick it to the man
|
||||||
|
toast lives on a sailboat with husband, daughters, and some pets
|
||||||
|
brains take pictures of them all and posts them on the Internets
|
||||||
|
pinky's in New Jersey, works at linode keeping servers up
|
||||||
|
crispy's got a dozen kids and writes code for some small start-up
|
||||||
|
alien's a British guy, his wife is French and they ride bikes
|
||||||
|
Fub's from Denmark, lives in London, wife and son are Chinese tykes
|
||||||
|
ameigh is a mommy and she studies speech impediments
|
||||||
|
nate's a mystery to me, I don't know how he pays his rents
|
||||||
|
ronin is a Star Wars fan, and coding's something he enjoys
|
||||||
|
heidi's pinky's wife, she has a business selling bedroom toys
|
||||||
|
kirk hacks Linux Kernels, and his paycheck comes from Cray Research
|
||||||
|
nwc's a mystery, he mostly hangs around and lurks
|
||||||
|
And me, I just sit around writing poems.
|
|
@ -0,0 +1,31 @@
|
||||||
|
This page is used to control what smileys are supported by the wiki.
|
||||||
|
Just write the text of a smiley to display it.
|
||||||
|
|
||||||
|
* \\:) [[smileys/smile.png]]
|
||||||
|
* \\:-) [[smileys/smile.png]]
|
||||||
|
* \\:D [[smileys/smile-big.png]]
|
||||||
|
* \\:-D [[smileys/smile-big.png]]
|
||||||
|
* \\;) [[smileys/wink.png]]
|
||||||
|
* \\;-) [[smileys/wink.png]]
|
||||||
|
* \\:\ [[smileys/thinking.png]]
|
||||||
|
* \\:-\ [[smileys/thinking.png]]
|
||||||
|
* \\:/ [[smileys/thinking.png]]
|
||||||
|
* \\:-/ [[smileys/thinking.png]]
|
||||||
|
* \\:| [[smileys/neutral.png]]
|
||||||
|
* \\:-| [[smileys/neutral.png]]
|
||||||
|
* \\:( [[smileys/sad.png]]
|
||||||
|
* \\:-( [[smileys/sad.png]]
|
||||||
|
* \\:-? [[smileys/tongue.png]]
|
||||||
|
* \\:-P [[smileys/tongue.png]]
|
||||||
|
* \\:o [[smileys/shock.png]]
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
To change the supported smileys, just edit the lists on this page.
|
||||||
|
Note that the format is important; each list item should start with the
|
||||||
|
text that is turned into the smiley, escaped so that users can see what
|
||||||
|
produces it, followed by a [[ikiwiki/WikiLink]] to the image to display.
|
||||||
|
|
||||||
|
/!\ Bear in mind that the link to the image needs to be written in a way that
|
||||||
|
will work if it's copied to other pages on the wiki. So be sure to include the
|
||||||
|
smileys directory in the path to the file.
|
|
@ -0,0 +1,31 @@
|
||||||
|
[[!meta title="Software"]]
|
||||||
|
|
||||||
|
I write software for a living. I like doing it so much that sometimes I
|
||||||
|
even write software just for fun. Here are some of the better hacks I've
|
||||||
|
created over the years.
|
||||||
|
|
||||||
|
[Firebot](firebot) is an IRC automaton (bot) that works as an InfoBot,
|
||||||
|
LinkBot (links multiple channels, even across servers), command bot
|
||||||
|
(displays the output of programs), web bot (fetches and parses web
|
||||||
|
pages, returning the results), and more. Everything runs in an
|
||||||
|
asynchronous select() loop with a very easy-to-use high-level interface.
|
||||||
|
|
||||||
|
[Photobob](photobob) is a web-based photo album. There's nothing to
|
||||||
|
differentiate this from the myriad other web-based photo albums out
|
||||||
|
there, except that this one doesn't need a database and doesn't write
|
||||||
|
any meta-information. You just point it at a directory full of
|
||||||
|
images/movies and it serves 'em up.
|
||||||
|
|
||||||
|
[eguile](eguile) is a text preprocessor using guile scheme.
|
||||||
|
[escm](escm) is the same thing for gauche. You could use these to build
|
||||||
|
a web site with a common theme. I used to use them, but now I use a
|
||||||
|
very simple m4 template.
|
||||||
|
|
||||||
|
The [Universal Boardgame Kit](ubk/) is a kit you can build for under $5
|
||||||
|
to use with a number of boardgames. A few boards are included. I
|
||||||
|
designed the pieces and most of the boards, and hand-coded them all in
|
||||||
|
PostScript. That makes me feel manly.
|
||||||
|
|
||||||
|
I also have some little [Python](python/), [PostScript](ps-hacks), and
|
||||||
|
[other](misc) hacks, which do clever things.
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
[[!meta title="Eguile : a scheme preprocessor"]]
|
||||||
|
|
||||||
|
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](scheme/eguile.scm).
|
||||||
|
|
||||||
|
|
||||||
|
## Reference
|
||||||
|
|
||||||
|
Easy squeezy:
|
||||||
|
|
||||||
|
<dl>
|
||||||
|
<dt><?scm scheme-code ?></dt>
|
||||||
|
<dd>Evaluates scheme-code, discarding value of the last expression</dd>
|
||||||
|
|
||||||
|
<dt><?scm:d scheme-code ?></dt>
|
||||||
|
<dd>Evaluates scheme-code, displaying the value of the last expression</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
<?scm (define (square x) (* x x)) ?>
|
||||||
|
2 squared is <?scm:d (square 2) ?>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
## Help me help you!
|
||||||
|
|
||||||
|
I don't honestly expect anyone to use eguile, so I'm not going to put
|
||||||
|
much into it beyond this page and what improvements I personally
|
||||||
|
need. If you do end up using it, please let me know! I'd be more than
|
||||||
|
happy to help you through any rough spots, and to consider any
|
||||||
|
suggestions. If nothing else, I can link to your pages as another
|
||||||
|
example of eguile in use :)
|
|
@ -0,0 +1,54 @@
|
||||||
|
[[!meta 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/gitweb.cgi?p=escm;a=snapshot), or check it out yourself:
|
||||||
|
|
||||||
|
git clone http://woozle.org/~neale/repos/escm
|
||||||
|
|
||||||
|
|
||||||
|
Reference
|
||||||
|
---------
|
||||||
|
|
||||||
|
Easy squeezy:
|
||||||
|
|
||||||
|
<dl>
|
||||||
|
<dt><?scm scheme-code ?></dt>
|
||||||
|
<dd>Evaluates scheme-code, discarding value of the last expression</dd>
|
||||||
|
|
||||||
|
<dt><?scm:d scheme-code ?></dt>
|
||||||
|
<dd>Evaluates scheme-code, displaying the value of the last expression</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
<?scm (define (square x) (* x x)) ?>
|
||||||
|
2 squared is <?scm:d (square 2) ?>
|
||||||
|
|
||||||
|
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
|
|
@ -0,0 +1,167 @@
|
||||||
|
[[!meta title="Firebot"]]
|
||||||
|
|
||||||
|
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/gitweb.cgi?p=firebot;a=snapshot;h=HEAD), or use cogito:
|
||||||
|
|
||||||
|
git clone http://woozle.org/~neale/repos/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.
|
||||||
|
|
||||||
|
<dl>
|
||||||
|
<dt>firebot, _x_</dt>
|
||||||
|
<dd>look up a factoid for _x_</dd>
|
||||||
|
|
||||||
|
<dt>firebot, _x_ is _y_</dt>
|
||||||
|
<dd>store _y_ as a factiod about _x_</dd>
|
||||||
|
|
||||||
|
<dt>firebot, _x_ is also _y_</dt>
|
||||||
|
<dd>store _y_ as another factoid about _x_</dd>
|
||||||
|
|
||||||
|
<dt>firebot, append _x_ <= _y_</dt>
|
||||||
|
<dd>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.</dd>
|
||||||
|
|
||||||
|
<dt>no, firebot, _x_ is _y_</dt>
|
||||||
|
<dd>store _y_ as the only factoid about _x_, even if _x_ already has factoids</dd>
|
||||||
|
|
||||||
|
<dt>firebot, literal _x_</dt>
|
||||||
|
<dd>display all factoids about _x_</dd>
|
||||||
|
|
||||||
|
<dt>firebot, lock _x_</dt>
|
||||||
|
<dd>do not learn any more factoids about _x_</dd>
|
||||||
|
|
||||||
|
<dt>firebot, unlock _x_</dt>
|
||||||
|
<dd>resume learning factoids about _x_</dd>
|
||||||
|
|
||||||
|
<dt>firebot, forget _x_</dt>
|
||||||
|
<dd>forget all factoids about _x_</dd>
|
||||||
|
|
||||||
|
<dt>firebot, forget _x_ from _y_</dt>
|
||||||
|
<dd>forget a single entry (<em>x</em>) that is listed in _y_; _x_ can be a single word, it does not need to be the whole entry</dd>
|
||||||
|
|
||||||
|
<dt>firebot, shut up</td>
|
||||||
|
<dd>make the bot only respond to factoids when addressed specifically</dd>
|
||||||
|
|
||||||
|
<dt>firebot, be chatty</td>
|
||||||
|
<dd>make the bot respond to factoids even when not addressed</dd>
|
||||||
|
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
In addition, the following tricks can be used within factiods:
|
||||||
|
|
||||||
|
* Any factoid beginning with `\\` (a backslash) is displayed directly.
|
||||||
|
That is, instead of saying "<firebot> x is y", FireBot just says
|
||||||
|
"<firebot> y".
|
||||||
|
* Any factoid beginning with <code>:</code> (a colon) is
|
||||||
|
displayed an action. That is, instead of saying "<firebot> 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
|
||||||
|
---------
|
||||||
|
|
||||||
|
<dl>
|
||||||
|
|
||||||
|
<dt>firebot, later tell _whom_ _what_</dt>
|
||||||
|
<dd>The next time _whom_ says something in the channel, deliver the message _what_ publically.</dd>
|
||||||
|
|
||||||
|
<dt>firebot, in _time_ say _what_</dt>
|
||||||
|
<dd>after _time_ (eg. "15 seconds", "2 hours", "5 days"), announce _what_ in the channel</dd>
|
||||||
|
|
||||||
|
<dt>seen _whom_</dt>
|
||||||
|
<dd>Report the last thing said in the channel by _whom_, and how long ago it was said.</dd>
|
||||||
|
|
||||||
|
<dt>dict _word_</dt>
|
||||||
|
<dd>look _word_ up in the dictionary</dd>
|
||||||
|
|
||||||
|
<dt>quote _symbol_</dt>
|
||||||
|
<dd>get a stock quote for _symbol_</dd>
|
||||||
|
|
||||||
|
<dt>pollen _zip_</dt>
|
||||||
|
<dd>report pollen forecast for US zip code _zip_</dd>
|
||||||
|
|
||||||
|
<dt>cdecl explain _jibberish_</dt>
|
||||||
|
<dd>explain the C declaration _jibberish_ (eg. "cdecl explain struct bar *(*foo)[](int)")</dd>
|
||||||
|
|
||||||
|
<dt>cdecl declare _english_</dt>
|
||||||
|
<dd>give the C declaration for _english_ (eg. "cdecl declare foo as pointer to array of function (int) returning pointer to struct bar")</dd>
|
||||||
|
|
||||||
|
<dt>how many _x_ in _y_ _z_</dt>
|
||||||
|
<dd>determine the number of _x_ items that are contained in _y_ amount of _z_ items (eg. how many miles in 1 light year)</dd>
|
||||||
|
|
||||||
|
<dt>how much is _amt_ _source_ in _dest_</dt>
|
||||||
|
<dd>do a currency conversion from _source_ to _dest_. Both must be three-letter currency codes. (eg. "how much is 100 USD in EUR")</dd>
|
||||||
|
|
||||||
|
<dt>calc _expr_</dt>
|
||||||
|
<dd>calculate _expr_ (eg. "calc 2 * 5")</dd>
|
||||||
|
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
|
||||||
|
Toys
|
||||||
|
----
|
||||||
|
|
||||||
|
<dl>
|
||||||
|
|
||||||
|
<dt>8ball, _question_</dt>
|
||||||
|
<dd>consult the magic 8-ball regarding _question_</dd>
|
||||||
|
|
||||||
|
<dt>_nickname_++</dt>
|
||||||
|
<dd>add a whuffie point for _nickname_</dd>
|
||||||
|
|
||||||
|
<dt>_nickname_--</dt>
|
||||||
|
<dd>remove a whuffie point for _nickname_</dd>
|
||||||
|
|
||||||
|
<dt>whuffie for _nickname_</dt>
|
||||||
|
<dd>check the whuffie for _nickname_</dd>
|
||||||
|
|
||||||
|
</dl>
|
|
@ -0,0 +1,62 @@
|
||||||
|
[[!meta title="Python ipqueue"]]
|
||||||
|
|
||||||
|
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 :)
|
||||||
|
|
||||||
|
Download
|
||||||
|
--------
|
||||||
|
|
||||||
|
* [Latest version](ipqueue.tar.gz)
|
||||||
|
* [Netfilter QUEUE bindings](nfqueue-0.1.tar.bz2) Mike Auty <mike.auty@gmail.com>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
|
||||||
|
GPL, of course.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
#! /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)
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
Help me out
|
||||||
|
-----------
|
||||||
|
|
||||||
|
If you're using this in a project, let me know and I'll link to it. If
|
||||||
|
you find any bugs, or want any features, please let me know about that
|
||||||
|
too. If you've got a hankering to write better documentation, that would
|
||||||
|
also be welcome :)
|
|
@ -0,0 +1 @@
|
||||||
|
ipqueue-1.4.1.tar.gz
|
|
@ -0,0 +1,59 @@
|
||||||
|
[[!meta title="Photobob"]]
|
||||||
|
|
||||||
|
I don't have a lot to say about photobob. It's the 7th or so photo
|
||||||
|
album package I've written, and probably the best. You just put
|
||||||
|
pictures and movies in a directory, and away you go. This works
|
||||||
|
really well with [an automated digicam photo sucking
|
||||||
|
thing](/~neale/blog/2006-10-18.The_automatic_camera_suck_script/).
|
||||||
|
|
||||||
|
Like all web applications I write, photobob does not use tables for
|
||||||
|
layout, and will change layout depending on your browser's width. It
|
||||||
|
uses CSS but still looks passable in non-CSS browsers. There is no
|
||||||
|
database back-end because it doesn't need one. It's just files in
|
||||||
|
directories.
|
||||||
|
|
||||||
|
Motivation
|
||||||
|
----------
|
||||||
|
|
||||||
|
I want my photo albums to survive longer than the software that serves
|
||||||
|
them up. My grandparents have shoeboxes full of photos, categorized by
|
||||||
|
date and event. This is nice because it doesn't require any additional
|
||||||
|
tools to determine the categorization.
|
||||||
|
|
||||||
|
All the web-based photo albums I've run across require some way to store
|
||||||
|
metadata. In one extreme example (PHP Gallery), all the images are
|
||||||
|
stored in one flat directory. Should the metadata ever become corrupted
|
||||||
|
or disappear, or should you decide to switch programs, you're left with
|
||||||
|
a huge mess and your categorization work is lost.
|
||||||
|
|
||||||
|
Photobob uses the file system as its categorization. You put photos in
|
||||||
|
directories, and attach comments to the photos themselves (using the
|
||||||
|
JFIF comment field). This makes it easy to press CDs or DVDs of your
|
||||||
|
photo albums and still preserve the categorization and narration you've
|
||||||
|
done. Should you decide to quit using Photobob, your photos will still
|
||||||
|
be tucked away in their directories, with no droppings from the album
|
||||||
|
software.
|
||||||
|
|
||||||
|
Photobob also takes advantage of a special property of JPEG files: size
|
||||||
|
reductions by powers of two (½, ¼, 1/8, etc.) are a very inexpensive
|
||||||
|
operation when done at decoding time. Additionally, many digital
|
||||||
|
cameras write small "thumbnail" images in the JFIF headers. Photobob
|
||||||
|
takes advantage of both of these properties to serve up scaled images
|
||||||
|
quickly and without needing to write anything to the hard drive.
|
||||||
|
|
||||||
|
|
||||||
|
Getting it
|
||||||
|
----------
|
||||||
|
|
||||||
|
It's not really packaged up for distribution, but that's only because I
|
||||||
|
doubt anyone will want it. If you're interested in trying it out on
|
||||||
|
your site, email me and I'll be glad to help you set it up.
|
||||||
|
|
||||||
|
You can check out the [woozle albums](http://woozle.org/albums)
|
||||||
|
for a live demo.
|
||||||
|
|
||||||
|
To get your own copy, run
|
||||||
|
|
||||||
|
git clone http://woozle.org/~neale/repos/photobob
|
||||||
|
|
||||||
|
Or you can do a [download the latest commit as a tarball](http://woozle.org/~neale/gitweb.cgi?p=photobob;a=snapshot;h=HEAD).
|
|
@ -0,0 +1,89 @@
|
||||||
|
[[!meta title="pysieved: Python Managesieve Server"]]
|
||||||
|
|
||||||
|
This is a GPL managesieve server. It uses a plug-in architecture to
|
||||||
|
support different authentication, homedir lookup, and storage
|
||||||
|
back-ends.
|
||||||
|
|
||||||
|
I wrote this so I could use avelsieve (SquirrelMail) with Postfix
|
||||||
|
and Dovecot. It should work with other managesieve clients too.
|
||||||
|
Please share with me your successes and failures.
|
||||||
|
|
||||||
|
|
||||||
|
Plugin architecture
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
The server ships with the following plug-ins:
|
||||||
|
|
||||||
|
Authentication:
|
||||||
|
|
||||||
|
* Dovecot
|
||||||
|
* PAM
|
||||||
|
* SASL
|
||||||
|
* MySQL
|
||||||
|
|
||||||
|
Homedir lookup & session initiation:
|
||||||
|
|
||||||
|
* Dovecot
|
||||||
|
* /etc/passwd
|
||||||
|
* MySQL
|
||||||
|
* simple virtual hosting (eg. /var/lib/virtual/username)
|
||||||
|
|
||||||
|
Storage:
|
||||||
|
|
||||||
|
* Dovecot
|
||||||
|
|
||||||
|
|
||||||
|
Additional back-ends are easy to write, just copy one of the existing
|
||||||
|
back-ends and start hacking. No modifications are needed to any
|
||||||
|
existing code, so you don't have to worry about things like the
|
||||||
|
managesieve protocol or forking.
|
||||||
|
|
||||||
|
|
||||||
|
Download
|
||||||
|
--------
|
||||||
|
|
||||||
|
[Version 1.0](http://woozle.org/~neale/gitweb.cgi?p=pysieved;a=commit;h=1.0)
|
||||||
|
was released on May 10, 2008 after release candidate 3 had been out for
|
||||||
|
6 weeks with no bug reports.
|
||||||
|
|
||||||
|
You can get the latest version [as
|
||||||
|
a tarball](http://woozle.org/~neale/gitweb.cgi?p=pysieved;a=snapshot;h=HEAD),
|
||||||
|
or with git:
|
||||||
|
|
||||||
|
git clone http://woozle.org/~neale/repos/pysieved
|
||||||
|
|
||||||
|
A [web view of revisions](http://woozle.org/~neale/gitweb.cgi?p=pysieved) is
|
||||||
|
also available for those without git.
|
||||||
|
|
||||||
|
|
||||||
|
Installation
|
||||||
|
------------
|
||||||
|
|
||||||
|
Put all the files somewhere. I put mine in /usr/local/lib/pysieved.
|
||||||
|
Copy pysieved.ini into /usr/local/etc/, and edit to taste. It's
|
||||||
|
commented.
|
||||||
|
|
||||||
|
To run from inetd, add the following line to /etc/inetd.conf:
|
||||||
|
|
||||||
|
sieve stream tcp nowait root /usr/bin/python python /usr/local/lib/pysieved/pysieved.py --inetd
|
||||||
|
|
||||||
|
To run as a daemon, just run
|
||||||
|
|
||||||
|
python pysieved.py
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Mail list / IRC channel
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
If you use pysieved, please join the pysieved mail list by emailing
|
||||||
|
[pysieved-subscribe@woozle.org](mailto:pysieved-subscribe@woozle.org) or
|
||||||
|
visiting the [subscription page](http://woozle.org/lists/pysieved).
|
||||||
|
|
||||||
|
To talk about pysieved on IRC, join us in
|
||||||
|
[#pysieved on irc.oftc.net](irc://irc.oftc.net/pysieved).
|
||||||
|
|
||||||
|
--------
|
||||||
|
|
||||||
|
Neale Pickett <neale@woozle.org>
|
|
@ -0,0 +1,111 @@
|
||||||
|
[[!meta title="xss"]]
|
||||||
|
|
||||||
|
[xss](http://woozle.org/~neale/src/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/gitweb.cgi?p=xss),
|
||||||
|
download a [tarball of the latest
|
||||||
|
commit](http://woozle.org/~neale/gitweb.cgi?p=xss;a=snapshot), or clone the
|
||||||
|
git repository:
|
||||||
|
|
||||||
|
git clone http://woozle.org/~neale/repos/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.
|
||||||
|
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
Neale Pickett <neale@woozle.org>
|
|
@ -0,0 +1,14 @@
|
||||||
|
[[!meta title="Toys"]]
|
||||||
|
|
||||||
|
Some various junk I've done. Maybe you'll find it amusing. Maybe
|
||||||
|
you'll just wonder why I spend so much time on this garbage.
|
||||||
|
|
||||||
|
* This [A Mind Forever Voyaging Decoder](amfv-decoder.cgi) is the sort
|
||||||
|
of thing where you'll only know what it is if you have a need for it.
|
||||||
|
* Play [a fun game](fungame)!
|
||||||
|
* Or you could play [robotfindskitten](robotfindskitten.cgi), which is
|
||||||
|
also fun!
|
||||||
|
* If you need to write someone a letter but really don't want to, try my
|
||||||
|
[smalltalk generator](smalltalk.cgi).
|
||||||
|
* Maybe you'd rather see a [magic trick](omg-magic)?
|
||||||
|
* How about some [Internet Reiki](reiki)?
|
|
@ -0,0 +1,20 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>crunt</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<?php
|
||||||
|
$crunts = rand() % 500;
|
||||||
|
$baby = $crunts * 0.75;
|
||||||
|
for ($i = 1; $i < $crunts; $i += 1) {
|
||||||
|
if (($i < $baby)
|
||||||
|
&& (rand() % 10 > 7)) {
|
||||||
|
print "<strong>CRUNT</strong> ";
|
||||||
|
} else {
|
||||||
|
print "crunt ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print "<strong>CRUNT!</strong>";
|
||||||
|
?>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,31 @@
|
||||||
|
[[!meta title="Fun Game"]]
|
||||||
|
|
||||||
|
<a name="part1"></a>
|
||||||
|
|
||||||
|
Let's play a fun game.
|
||||||
|
|
||||||
|
You think of a number between 1 and 100, and I'll try to guess
|
||||||
|
it.
|
||||||
|
|
||||||
|
When you've thought of your number, click [here](#part2).
|
||||||
|
|
||||||
|
<br style="margin-top: 200%;" />
|
||||||
|
<a name="part2"></a>
|
||||||
|
|
||||||
|
Is your number 7?
|
||||||
|
|
||||||
|
* [Yes](#part3)
|
||||||
|
* [No](#part2)
|
||||||
|
|
||||||
|
|
||||||
|
<br style="margin-top: 200%;" />
|
||||||
|
<a name="part3"></a>
|
||||||
|
|
||||||
|
Yay, I win!
|
||||||
|
|
||||||
|
Would you like to play again?
|
||||||
|
|
||||||
|
* [Yes](#part1)
|
||||||
|
* [No](#part1)
|
||||||
|
|
||||||
|
<br style="margin-top: 100%;" />
|
|
@ -0,0 +1,72 @@
|
||||||
|
[[!meta title="OMG Magic!"]]
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This is a clever magic trick. This paragraph should be filled with
|
||||||
|
suspenseful leadup to waste your time and get you TOTALLY PUMPED for
|
||||||
|
this AWESOME MAGIC TRICK that was created by some famous and/or
|
||||||
|
mystical person and now it's coming <b>directly to you</b> on the
|
||||||
|
Internets! Can you believe it!
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Pick a card. Stare at it long enough to memorize what card you've
|
||||||
|
picked, try to burn it into you mind. Don't worry, take your time,
|
||||||
|
I'll wait.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div style="text-align: center;">
|
||||||
|
<img alt="card" src="12.png" />
|
||||||
|
<img alt="card" src="13.png" />
|
||||||
|
<img alt="card" src="7.png" />
|
||||||
|
<img alt="card" src="10.png" />
|
||||||
|
<img alt="card" src="6.png" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
When you've memorized your card, you may <a href="#part2">proceed to
|
||||||
|
the next page</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<br style="margin-top: 200%;" />
|
||||||
|
<a name="part2"></a>
|
||||||
|
|
||||||
|
<h1>OMG Magic!</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Do you remember your card? I'm going to yak at you for a little while
|
||||||
|
to make you spend some time doing something other than focusing on
|
||||||
|
those cards. This is called <em>redirection</em> and it's a
|
||||||
|
fundamental part of most magic tricks. The fact that it works even in
|
||||||
|
a web page says more about humanity than you in particular, so don't
|
||||||
|
feel bad.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Ready to have you mind blown? <a href="#part3">Let's go!</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<br style="margin-top: 200%;" />
|
||||||
|
<a name="part3"></a>
|
||||||
|
|
||||||
|
<h1>OMG Magic!</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
I have removed your card from the hand!
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div style="text-align: center;">
|
||||||
|
<img alt="card" src="15.png" />
|
||||||
|
<img alt="card" src="8.png" />
|
||||||
|
<img alt="card" src="9.png" />
|
||||||
|
<img alt="card" src="14.png" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>
|
||||||
|
Did it work?
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<h2>
|
||||||
|
OMG Magic!
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<br style="margin-top: 100%;" />
|
After Width: | Height: | Size: 440 B |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 623 B |
After Width: | Height: | Size: 596 B |
After Width: | Height: | Size: 630 B |
After Width: | Height: | Size: 583 B |
After Width: | Height: | Size: 554 B |
After Width: | Height: | Size: 679 B |
After Width: | Height: | Size: 608 B |
After Width: | Height: | Size: 634 B |
After Width: | Height: | Size: 533 B |
After Width: | Height: | Size: 612 B |
After Width: | Height: | Size: 618 B |
After Width: | Height: | Size: 625 B |
After Width: | Height: | Size: 525 B |
After Width: | Height: | Size: 610 B |
After Width: | Height: | Size: 453 B |
After Width: | Height: | Size: 609 B |
After Width: | Height: | Size: 606 B |
After Width: | Height: | Size: 513 B |
After Width: | Height: | Size: 510 B |
After Width: | Height: | Size: 520 B |
After Width: | Height: | Size: 531 B |
After Width: | Height: | Size: 463 B |
After Width: | Height: | Size: 553 B |
After Width: | Height: | Size: 558 B |
After Width: | Height: | Size: 578 B |
After Width: | Height: | Size: 388 B |
After Width: | Height: | Size: 478 B |
After Width: | Height: | Size: 474 B |
After Width: | Height: | Size: 486 B |
After Width: | Height: | Size: 494 B |
After Width: | Height: | Size: 435 B |
After Width: | Height: | Size: 505 B |
After Width: | Height: | Size: 511 B |
After Width: | Height: | Size: 508 B |
After Width: | Height: | Size: 440 B |
After Width: | Height: | Size: 457 B |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 463 B |
After Width: | Height: | Size: 474 B |
After Width: | Height: | Size: 411 B |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 3.0 KiB |