The .conkyrc I am using on my DevTerm.

.conkyrc
conky.config = {
border_width = 1,
cpu_avg_samples = 2,
default_color = 'white',
minimum_width = 5,
default_graph_width = 200,
default_graph_height = 40,
default_gauge_width = 200,
alignment = 'top_left',
background = false,
default_outline_color = 'white',
default_shade_color = 'CornflowerBlue',
draw_borders = false,
draw_graph_borders = true,
draw_outline = false,
draw_shades = false,
extra_newline = false,
font = '6x13',
gap_x = 0,
gap_y = 6,
minimum_height = 3,
net_avg_samples = 2,
no_buffers = true,
double_buffer = true,
out_to_console = false,
out_to_stderr = false,
own_window = false,
own_window_class = 'Conky',
own_window_type = 'desktop',
show_graph_range = false,
show_graph_scale = false,
stippled_borders = 0,
--update_interval = 10.0,
update_interval = 1.5, -- 2.7,
uppercase = false,
use_spacer = 'none',
use_xft = false,
color0 = 'fff8e0',
color1 = 'ff2222',
color2 = '00ee00',
color3 = 'bb8833',
color4 = '0072ff',
color5 = '706c9a',
color6 = '00aabb',
color7 = 'efef60',
color8 = '999999',
color9 = 'ff8442',
}
-- urxvt*background: #000008
-- urxvt*foreground: #fff8e0
conky.text = [[
$color0${no_update $nodename}${execi 90001 echo $DISPLAY} ${no_update $sysname} ${no_update $kernel}/${no_update $machine}$color
${color8}Uptime:$color $uptime ${color8}Load:$color ${loadavg}
${color0}${time}$color | ${color9}${execi 11 /home/pete/bin/battery}${color}
${color8}${tztime America/Los_Angeles}$color | ${color7} $acpitemp°C${color} | $color6 BL: ${execi 13 /home/pete/bin/cbl}
${color4}[CPU:$color $cpu% ${freq_g}GHz ${color4}]${hr}$color
${color white}${cpugraph 40,270 00e4ff ff4da1 -t}$color
${cpugraph cpu1 15,40 224422 0072ff -t} ${cpugraph cpu2 15,40 222244 00aabb -t} ${cpugraph cpu3 15,40 222244 0072ff -t} ${cpugraph cpu4 15,40 224422 00aabb -t} ${cpugraph cpu5 15,40 442222 ff8442 -t} ${cpugraph cpu6 15,40 442222 ff8442 -t}
${color8}RAM: $color $mem/$memmax - $memperc% ${membar 4}
${color8}Swap:$color $swap/$swapmax - $swapperc% ${swapbar 4}
${color4}[FS]${hr}$color
${color white}/ $color${fs_used_perc /}% used / ${fs_free /} free
${fs_bar 6 /}
${color white}/tmp $color${fs_used_perc /tmp}% used / ${fs_free /tmp} free
${fs_bar 6 /tmp}${if_mounted /opt/tmp}
${color white}/opt/tmp $color${fs_used_perc /opt/tmp}% used / ${fs_free /opt/tmp} free
${fs_bar 6 /opt/tmp}${endif}${if_mounted /mnt}
${color white}/mnt $color${fs_used_perc /mnt}% used / ${fs_free /mnt} free
${fs_bar 6 /mnt}${endif}
${color4}[wlan0 $color${wireless_essid wlan0} $color8${addr wlan0}${color4}]${hr}$color
[${wireless_link_qual wlan0}] ${wireless_link_bar 8,60 wlan0} (${wireless_link_qual_perc wlan0}%) ${wireless_bitrate wlan0} @ ${wireless_freq wlan0}
UP: ${upspeedgraph wlan0 10,150 004da1 ff4da1 -t} ${upspeed wlan0}
DOWN: ${downspeedgraph wlan0 10,150 ff00a1 ffffa1 -t} ${downspeed wlan0}
${color4}[PS]${hr}$color
${color8}Name PID CPU% MEM%
${color #fff8e0}${top name 1} ${top pid 1} ${top cpu 1} ${top mem 1}
${color lightgrey}${top name 2} ${top pid 2} ${top cpu 2} ${top mem 2}
${color lightgrey}${top name 3} ${top pid 3} ${top cpu 3} ${top mem 3}
${color lightgrey}${top name 4} ${top pid 4} ${top cpu 4} ${top mem 4}
${color lightgrey}${top name 5} ${top pid 5} ${top cpu 5} ${top mem 5}
${color lightgrey}${top name 6} ${top pid 6} ${top cpu 6} ${top mem 6}
${color lightgrey}${top name 7} ${top pid 7} ${top cpu 7} ${top mem 7}
]]

Various implementations of the 'cat' command, for comparison.

0-README
I turned this gist into a "real" repository. It is here: http://github.com/pete/cats .
Here, placed side-by-side for comparison, are GNU's implementation of
cat, Plan 9's implementation, Busybox's implementation, and NetBSD's
implementation, Seventh Edition Unix (1979), and 4.3BSD.
For good measure (and because I suppose I am now committed to collecting
cats) also included are Second Edition Unix (in assembly) and Inferno's
implementation (in Limbo) for good measure.
All cat.c files (renamed by prefixing the name of the source source) are
presented, unaltered and in their entirety. Note how easy it is to read
and understand plan9-cat.c (it should take less than a couple of minutes
possibly even for coders that don't know C). Other than that, I think
the files speak for themselves.
Keep in mind while reading that the cat utility's purpose is to
concatenate files.
Lastly, here are the line and character counts, sorted:
Lines Chars Filename
---------------------------
35 531 plan9-cat.c
48 955 busybox-cat.c
48 986 inferno-cat.b
63 1130 unix7-cat.c
64 646 unix2-cat.s
222 3948 4.3bsd-cat.c
316 6952 netbsd-cat.c
782 22684 gnu-cat.c
1578 37832 total
4.3bsd-cat.c
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*/
#ifndef lint
static char sccsid[] = "@(#)cat.c 5.2 (Berkeley) 12/6/85";
#endif not lint
/*
* Concatenate files.
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
/* #define OPTSIZE BUFSIZ /* define this only if not 4.2 BSD or beyond */
int bflg, eflg, nflg, sflg, tflg, uflg, vflg;
int spaced, col, lno, inline, ibsize, obsize;
main(argc, argv)
char **argv;
{
int fflg = 0;
register FILE *fi;
register c;
int dev, ino = -1;
struct stat statb;
int retval = 0;
lno = 1;
for( ; argc>1 && argv[1][0]=='-'; argc--,argv++) {
switch(argv[1][1]) {
case 0:
break;
case 'u':
setbuf(stdout, (char *)NULL);
uflg++;
continue;
case 'n':
nflg++;
continue;
case 'b':
bflg++;
nflg++;
continue;
case 'v':
vflg++;
continue;
case 's':
sflg++;
continue;
case 'e':
eflg++;
vflg++;
continue;
case 't':
tflg++;
vflg++;
continue;
}
break;
}
if (fstat(fileno(stdout), &statb) == 0) {
statb.st_mode &= S_IFMT;
if (statb.st_mode!=S_IFCHR && statb.st_mode!=S_IFBLK) {
dev = statb.st_dev;
ino = statb.st_ino;
}
#ifndef OPTSIZE
obsize = statb.st_blksize;
#endif
}
else
obsize = 0;
if (argc < 2) {
argc = 2;
fflg++;
}
while (--argc > 0) {
if (fflg || (*++argv)[0]=='-' && (*argv)[1]=='\0')
fi = stdin;
else {
if ((fi = fopen(*argv, "r")) == NULL) {
perror(*argv);
retval = 1;
continue;
}
}
if (fstat(fileno(fi), &statb) == 0) {
if ((statb.st_mode & S_IFMT) == S_IFREG &&
statb.st_dev==dev && statb.st_ino==ino) {
fprintf(stderr, "cat: input %s is output\n",
fflg?"-": *argv);
fclose(fi);
retval = 1;
continue;
}
#ifndef OPTSIZE
ibsize = statb.st_blksize;
#endif
}
else
ibsize = 0;
if (nflg||sflg||vflg)
copyopt(fi);
else if (uflg) {
while ((c = getc(fi)) != EOF)
putchar(c);
} else
retval |= fastcat(fileno(fi)); /* no flags specified */
if (fi!=stdin)
fclose(fi);
else
clearerr(fi); /* reset sticky eof */
if (ferror(stdout)) {
fprintf(stderr, "cat: output write error\n");
retval = 1;
break;
}
}
exit(retval);
}
copyopt(f)
register FILE *f;
{
register int c;
top:
c = getc(f);
if (c == EOF)
return;
if (c == '\n') {
if (inline == 0) {
if (sflg && spaced)
goto top;
spaced = 1;
}
if (nflg && bflg==0 && inline == 0)
printf("%6d\t", lno++);
if (eflg)
putchar('$');
putchar('\n');
inline = 0;
goto top;
}
if (nflg && inline == 0)
printf("%6d\t", lno++);
inline = 1;
if (vflg) {
if (tflg==0 && c == '\t')
putchar(c);
else {
if (c > 0177) {
printf("M-");
c &= 0177;
}
if (c < ' ')
printf("^%c", c+'@');
else if (c == 0177)
printf("^?");
else
putchar(c);
}
} else
putchar(c);
spaced = 0;
goto top;
}
fastcat(fd)
register int fd;
{
register int buffsize, n, nwritten, offset;
register char *buff;
struct stat statbuff;
char *malloc();
#ifndef OPTSIZE
if (obsize)
buffsize = obsize; /* common case, use output blksize */
else if (ibsize)
buffsize = ibsize;
else
buffsize = BUFSIZ;
#else
buffsize = OPTSIZE;
#endif
if ((buff = malloc(buffsize)) == NULL) {
perror("cat: no memory");
return (1);
}
/*
* Note that on some systems (V7), very large writes to a pipe
* return less than the requested size of the write.
* In this case, multiple writes are required.
*/
while ((n = read(fd, buff, buffsize)) > 0) {
offset = 0;
do {
nwritten = write(fileno(stdout), &buff[offset], n);
if (nwritten <= 0) {
perror("cat: write error");
exit(2);
}
offset += nwritten;
} while ((n -= nwritten) > 0);
}
free(buff);
if (n < 0) {
perror("cat: read error");
return (1);
}
return (0);
}
busybox-cat.c
/* vi: set sw=4 ts=4: */
/*
* cat implementation for busybox
*
* Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
*
* Licensed under GPLv2, see file License in this tarball for details.
*/
/* BB_AUDIT SUSv3 compliant */
/* http://www.opengroup.org/onlinepubs/007904975/utilities/cat.html */
#include "libbb.h"
/* This is a NOFORK applet. Be very careful! */
int bb_cat(char **argv)
{
int fd;
int retval = EXIT_SUCCESS;
if (!*argv)
argv = (char**) &bb_argv_dash;
do {
fd = open_or_warn_stdin(*argv);
if (fd >= 0) {
/* This is not a xfunc - never exits */
off_t r = bb_copyfd_eof(fd, STDOUT_FILENO);
if (fd != STDIN_FILENO)
close(fd);
if (r >= 0)
continue;
}
retval = EXIT_FAILURE;
} while (*++argv);
return retval;
}
int cat_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int cat_main(int argc ATTRIBUTE_UNUSED, char **argv)
{
getopt32(argv, "u");
argv += optind;
return bb_cat(argv);
}
gnu-cat.c
/* cat -- concatenate files and print on the standard output.
Copyright (C) 1988, 1990-1991, 1995-2010 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* Differences from the Unix cat:
* Always unbuffered, -u is ignored.
* Usually much faster than other versions of cat, the difference
is especially apparent when using the -v option.
By tege@sics.se, Torbjorn Granlund, advised by rms, Richard Stallman. */
#include <config.h>
#include <stdio.h>
#include <getopt.h>
#include <sys/types.h>
#if HAVE_STROPTS_H
# include <stropts.h>
#endif
#if HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#include "system.h"
#include "error.h"
#include "full-write.h"
#include "quote.h"
#include "safe-read.h"
#include "xfreopen.h"
/* The official name of this program (e.g., no `g' prefix). */
#define PROGRAM_NAME "cat"
#define AUTHORS \
proper_name_utf8 ("Torbjorn Granlund", "Torbj\303\266rn Granlund"), \
proper_name ("Richard M. Stallman")
/* Name of input file. May be "-". */
static char const *infile;
/* Descriptor on which input file is open. */
static int input_desc;
/* Buffer for line numbers.
An 11 digit counter may overflow within an hour on a P2/466,
an 18 digit counter needs about 1000y */
#define LINE_COUNTER_BUF_LEN 20
static char line_buf[LINE_COUNTER_BUF_LEN] =
{
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '0',
'\t', '\0'
};
/* Position in `line_buf' where printing starts. This will not change
unless the number of lines is larger than 999999. */
static char *line_num_print = line_buf + LINE_COUNTER_BUF_LEN - 8;
/* Position of the first digit in `line_buf'. */
static char *line_num_start = line_buf + LINE_COUNTER_BUF_LEN - 3;
/* Position of the last digit in `line_buf'. */
static char *line_num_end = line_buf + LINE_COUNTER_BUF_LEN - 3;
/* Preserves the `cat' function's local `newlines' between invocations. */
static int newlines2 = 0;
void
usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
else
{
printf (_("\
Usage: %s [OPTION]... [FILE]...\n\
"),
program_name);
fputs (_("\
Concatenate FILE(s), or standard input, to standard output.\n\
\n\
-A, --show-all equivalent to -vET\n\
-b, --number-nonblank number nonempty output lines\n\
-e equivalent to -vE\n\
-E, --show-ends display $ at end of each line\n\
-n, --number number all output lines\n\
-s, --squeeze-blank suppress repeated empty output lines\n\
"), stdout);
fputs (_("\
-t equivalent to -vT\n\
-T, --show-tabs display TAB characters as ^I\n\
-u (ignored)\n\
-v, --show-nonprinting use ^ and M- notation, except for LFD and TAB\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
fputs (_("\
\n\
With no FILE, or when FILE is -, read standard input.\n\
"), stdout);
printf (_("\
\n\
Examples:\n\
%s f - g Output f's contents, then standard input, then g's contents.\n\
%s Copy standard input to standard output.\n\
"),
program_name, program_name);
emit_ancillary_info ();
}
exit (status);
}
/* Compute the next line number. */
static void
next_line_num (void)
{
char *endp = line_num_end;
do
{
if ((*endp)++ < '9')
return;
*endp-- = '0';
}
while (endp >= line_num_start);
if (line_num_start > line_buf)
*--line_num_start = '1';
else
*line_buf = '>';
if (line_num_start < line_num_print)
line_num_print--;
}
/* Plain cat. Copies the file behind `input_desc' to STDOUT_FILENO.
Return true if successful. */
static bool
simple_cat (
/* Pointer to the buffer, used by reads and writes. */
char *buf,
/* Number of characters preferably read or written by each read and write
call. */
size_t bufsize)
{
/* Actual number of characters read, and therefore written. */
size_t n_read;
/* Loop until the end of the file. */
for (;;)
{
/* Read a block of input. */
n_read = safe_read (input_desc, buf, bufsize);
if (n_read == SAFE_READ_ERROR)
{
error (0, errno, "%s", infile);
return false;
}
/* End of this file? */
if (n_read == 0)
return true;
/* Write this block out. */
{
/* The following is ok, since we know that 0 < n_read. */
size_t n = n_read;
if (full_write (STDOUT_FILENO, buf, n) != n)
error (EXIT_FAILURE, errno, _("write error"));
}
}
}
/* Write any pending output to STDOUT_FILENO.
Pending is defined to be the *BPOUT - OUTBUF bytes starting at OUTBUF.
Then set *BPOUT to OUTPUT if it's not already that value. */
static inline void
write_pending (char *outbuf, char **bpout)
{
size_t n_write = *bpout - outbuf;
if (0 < n_write)
{
if (full_write (STDOUT_FILENO, outbuf, n_write) != n_write)
error (EXIT_FAILURE, errno, _("write error"));
*bpout = outbuf;
}
}
/* Cat the file behind INPUT_DESC to the file behind OUTPUT_DESC.
Return true if successful.
Called if any option more than -u was specified.
A newline character is always put at the end of the buffer, to make
an explicit test for buffer end unnecessary. */
static bool
cat (
/* Pointer to the beginning of the input buffer. */
char *inbuf,
/* Number of characters read in each read call. */
size_t insize,
/* Pointer to the beginning of the output buffer. */
char *outbuf,
/* Number of characters written by each write call. */
size_t outsize,
/* Variables that have values according to the specified options. */
bool show_nonprinting,
bool show_tabs,
bool number,
bool number_nonblank,
bool show_ends,
bool squeeze_blank)
{
/* Last character read from the input buffer. */
unsigned char ch;
/* Pointer to the next character in the input buffer. */
char *bpin;
/* Pointer to the first non-valid byte in the input buffer, i.e. the
current end of the buffer. */
char *eob;
/* Pointer to the position where the next character shall be written. */
char *bpout;
/* Number of characters read by the last read call. */
size_t n_read;
/* Determines how many consecutive newlines there have been in the
input. 0 newlines makes NEWLINES -1, 1 newline makes NEWLINES 1,
etc. Initially 0 to indicate that we are at the beginning of a
new line. The "state" of the procedure is determined by
NEWLINES. */
int newlines = newlines2;
#ifdef FIONREAD
/* If nonzero, use the FIONREAD ioctl, as an optimization.
(On Ultrix, it is not supported on NFS file systems.) */
bool use_fionread = true;
#endif
/* The inbuf pointers are initialized so that BPIN > EOB, and thereby input
is read immediately. */
eob = inbuf;
bpin = eob + 1;
bpout = outbuf;
for (;;)
{
do
{
/* Write if there are at least OUTSIZE bytes in OUTBUF. */
if (outbuf + outsize <= bpout)
{
char *wp = outbuf;
size_t remaining_bytes;
do
{
if (full_write (STDOUT_FILENO, wp, outsize) != outsize)
error (EXIT_FAILURE, errno, _("write error"));
wp += outsize;
remaining_bytes = bpout - wp;
}
while (outsize <= remaining_bytes);
/* Move the remaining bytes to the beginning of the
buffer. */
memmove (outbuf, wp, remaining_bytes);
bpout = outbuf + remaining_bytes;
}
/* Is INBUF empty? */
if (bpin > eob)
{
bool input_pending = false;
#ifdef FIONREAD
int n_to_read = 0;
/* Is there any input to read immediately?
If not, we are about to wait,
so write all buffered output before waiting. */
if (use_fionread
&& ioctl (input_desc, FIONREAD, &n_to_read) < 0)
{
/* Ultrix returns EOPNOTSUPP on NFS;
HP-UX returns ENOTTY on pipes.
SunOS returns EINVAL and
More/BSD returns ENODEV on special files
like /dev/null.
Irix-5 returns ENOSYS on pipes. */
if (errno == EOPNOTSUPP || errno == ENOTTY
|| errno == EINVAL || errno == ENODEV
|| errno == ENOSYS)
use_fionread = false;
else
{
error (0, errno, _("cannot do ioctl on %s"), quote (infile));
newlines2 = newlines;
return false;
}
}
if (n_to_read != 0)
input_pending = true;
#endif
if (!input_pending)
write_pending (outbuf, &bpout);
/* Read more input into INBUF. */
n_read = safe_read (input_desc, inbuf, insize);
if (n_read == SAFE_READ_ERROR)
{
error (0, errno, "%s", infile);
write_pending (outbuf, &bpout);
newlines2 = newlines;
return false;
}
if (n_read == 0)
{
write_pending (outbuf, &bpout);
newlines2 = newlines;
return true;
}
/* Update the pointers and insert a sentinel at the buffer
end. */
bpin = inbuf;
eob = bpin + n_read;
*eob = '\n';
}
else
{
/* It was a real (not a sentinel) newline. */
/* Was the last line empty?
(i.e. have two or more consecutive newlines been read?) */
if (++newlines > 0)
{
if (newlines >= 2)
{
/* Limit this to 2 here. Otherwise, with lots of
consecutive newlines, the counter could wrap
around at INT_MAX. */
newlines = 2;
/* Are multiple adjacent empty lines to be substituted
by single ditto (-s), and this was the second empty
line? */
if (squeeze_blank)
{
ch = *bpin++;
continue;
}
}
/* Are line numbers to be written at empty lines (-n)? */
if (number && !number_nonblank)
{
next_line_num ();
bpout = stpcpy (bpout, line_num_print);
}
}
/* Output a currency symbol if requested (-e). */
if (show_ends)
*bpout++ = '$';
/* Output the newline. */
*bpout++ = '\n';
}
ch = *bpin++;
}
while (ch == '\n');
/* Are we at the beginning of a line, and line numbers are requested? */
if (newlines >= 0 && number)
{
next_line_num ();
bpout = stpcpy (bpout, line_num_print);
}
/* Here CH cannot contain a newline character. */
/* The loops below continue until a newline character is found,
which means that the buffer is empty or that a proper newline
has been found. */
/* If quoting, i.e. at least one of -v, -e, or -t specified,
scan for chars that need conversion. */
if (show_nonprinting)
{
for (;;)
{
if (ch >= 32)
{
if (ch < 127)
*bpout++ = ch;
else if (ch == 127)
{
*bpout++ = '^';
*bpout++ = '?';
}
else
{
*bpout++ = 'M';
*bpout++ = '-';
if (ch >= 128 + 32)
{
if (ch < 128 + 127)
*bpout++ = ch - 128;
else
{
*bpout++ = '^';
*bpout++ = '?';
}
}
else
{
*bpout++ = '^';
*bpout++ = ch - 128 + 64;
}
}
}
else if (ch == '\t' && !show_tabs)
*bpout++ = '\t';
else if (ch == '\n')
{
newlines = -1;
break;
}
else
{
*bpout++ = '^';
*bpout++ = ch + 64;
}
ch = *bpin++;
}
}
else
{
/* Not quoting, neither of -v, -e, or -t specified. */
for (;;)
{
if (ch == '\t' && show_tabs)
{
*bpout++ = '^';
*bpout++ = ch + 64;
}
else if (ch != '\n')
*bpout++ = ch;
else
{
newlines = -1;
break;
}
ch = *bpin++;
}
}
}
}
int
main (int argc, char **argv)
{
/* Optimal size of i/o operations of output. */
size_t outsize;
/* Optimal size of i/o operations of input. */
size_t insize;
size_t page_size = getpagesize ();
/* Pointer to the input buffer. */
char *inbuf;
/* Pointer to the output buffer. */
char *outbuf;
bool ok = true;
int c;
/* Index in argv to processed argument. */
int argind;
/* Device number of the output (file or whatever). */
dev_t out_dev;
/* I-node number of the output. */
ino_t out_ino;
/* True if the output file should not be the same as any input file. */
bool check_redirection = true;
/* Nonzero if we have ever read standard input. */
bool have_read_stdin = false;
struct stat stat_buf;
/* Variables that are set according to the specified options. */
bool number = false;
bool number_nonblank = false;
bool squeeze_blank = false;
bool show_ends = false;
bool show_nonprinting = false;
bool show_tabs = false;
int file_open_mode = O_RDONLY;
static struct option const long_options[] =
{
{"number-nonblank", no_argument, NULL, 'b'},
{"number", no_argument, NULL, 'n'},
{"squeeze-blank", no_argument, NULL, 's'},
{"show-nonprinting", no_argument, NULL, 'v'},
{"show-ends", no_argument, NULL, 'E'},
{"show-tabs", no_argument, NULL, 'T'},
{"show-all", no_argument, NULL, 'A'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
};
initialize_main (&argc, &argv);
set_program_name (argv[0]);
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
/* Arrange to close stdout if we exit via the
case_GETOPT_HELP_CHAR or case_GETOPT_VERSION_CHAR code.
Normally STDOUT_FILENO is used rather than stdout, so
close_stdout does nothing. */
atexit (close_stdout);
/* Parse command line options. */
while ((c = getopt_long (argc, argv, "benstuvAET", long_options, NULL))
!= -1)
{
switch (c)
{
case 'b':
number = true;
number_nonblank = true;
break;
case 'e':
show_ends = true;
show_nonprinting = true;
break;
case 'n':
number = true;
break;
case 's':
squeeze_blank = true;
break;
case 't':
show_tabs = true;
show_nonprinting = true;
break;
case 'u':
/* We provide the -u feature unconditionally. */
break;
case 'v':
show_nonprinting = true;
break;
case 'A':
show_nonprinting = true;
show_ends = true;
show_tabs = true;
break;
case 'E':
show_ends = true;
break;
case 'T':
show_tabs = true;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
}
/* Get device, i-node number, and optimal blocksize of output. */
if (fstat (STDOUT_FILENO, &stat_buf) < 0)
error (EXIT_FAILURE, errno, _("standard output"));
outsize = io_blksize (stat_buf);
/* Input file can be output file for non-regular files.
fstat on pipes returns S_IFSOCK on some systems, S_IFIFO
on others, so the checking should not be done for those types,
and to allow things like cat < /dev/tty > /dev/tty, checking
is not done for device files either. */
if (S_ISREG (stat_buf.st_mode))
{
out_dev = stat_buf.st_dev;
out_ino = stat_buf.st_ino;
}
else
{
check_redirection = false;
#ifdef lint /* Suppress `used before initialized' warning. */
out_dev = 0;
out_ino = 0;
#endif
}
if (! (number || show_ends || squeeze_blank))
{
file_open_mode |= O_BINARY;
if (O_BINARY && ! isatty (STDOUT_FILENO))
xfreopen (NULL, "wb", stdout);
}
/* Check if any of the input files are the same as the output file. */
/* Main loop. */
infile = "-";
argind = optind;
do
{
if (argind < argc)
infile = argv[argind];
if (STREQ (infile, "-"))
{
have_read_stdin = true;
input_desc = STDIN_FILENO;
if ((file_open_mode & O_BINARY) && ! isatty (STDIN_FILENO))
xfreopen (NULL, "rb", stdin);
}
else
{
input_desc = open (infile, file_open_mode);
if (input_desc < 0)
{
error (0, errno, "%s", infile);
ok = false;
continue;
}
}
if (fstat (input_desc, &stat_buf) < 0)
{
error (0, errno, "%s", infile);
ok = false;
goto contin;
}
insize = io_blksize (stat_buf);
/* Compare the device and i-node numbers of this input file with
the corresponding values of the (output file associated with)
stdout, and skip this input file if they coincide. Input
files cannot be redirected to themselves. */
if (check_redirection
&& stat_buf.st_dev == out_dev && stat_buf.st_ino == out_ino
&& (input_desc != STDIN_FILENO))
{
error (0, 0, _("%s: input file is output file"), infile);
ok = false;
goto contin;
}
/* Select which version of `cat' to use. If any format-oriented
options were given use `cat'; otherwise use `simple_cat'. */
if (! (number || show_ends || show_nonprinting
|| show_tabs || squeeze_blank))
{
insize = MAX (insize, outsize);
inbuf = xmalloc (insize + page_size - 1);
ok &= simple_cat (ptr_align (inbuf, page_size), insize);
}
else
{
inbuf = xmalloc (insize + 1 + page_size - 1);
/* Why are
(OUTSIZE - 1 + INSIZE * 4 + LINE_COUNTER_BUF_LEN + PAGE_SIZE - 1)
bytes allocated for the output buffer?
A test whether output needs to be written is done when the input
buffer empties or when a newline appears in the input. After
output is written, at most (OUTSIZE - 1) bytes will remain in the
buffer. Now INSIZE bytes of input is read. Each input character
may grow by a factor of 4 (by the prepending of M-^). If all
characters do, and no newlines appear in this block of input, we
will have at most (OUTSIZE - 1 + INSIZE * 4) bytes in the buffer.
If the last character in the preceding block of input was a
newline, a line number may be written (according to the given
options) as the first thing in the output buffer. (Done after the
new input is read, but before processing of the input begins.)
A line number requires seldom more than LINE_COUNTER_BUF_LEN
positions.
Align the output buffer to a page size boundary, for efficency on
some paging implementations, so add PAGE_SIZE - 1 bytes to the
request to make room for the alignment. */
outbuf = xmalloc (outsize - 1 + insize * 4 + LINE_COUNTER_BUF_LEN
+ page_size - 1);
ok &= cat (ptr_align (inbuf, page_size), insize,
ptr_align (outbuf, page_size), outsize, show_nonprinting,
show_tabs, number, number_nonblank, show_ends,
squeeze_blank);
free (outbuf);
}
free (inbuf);
contin:
if (!STREQ (infile, "-") && close (input_desc) < 0)
{
error (0, errno, "%s", infile);
ok = false;
}
}
while (++argind < argc);
if (have_read_stdin && close (STDIN_FILENO) < 0)
error (EXIT_FAILURE, errno, _("closing standard input"));
exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
}
inferno-cat.b
implement Cat;
include "sys.m";
sys: Sys;
include "draw.m";
Cat: module
{
init: fn(ctxt: ref Draw->Context, argv: list of string);
};
stdout: ref Sys->FD;
init(nil: ref Draw->Context, args: list of string)
{
sys = load Sys Sys->PATH;
stdout = sys->fildes(1);
args = tl args;
if(args == nil)
args = "-" :: nil;
for(; args != nil; args = tl args){
file := hd args;
if(file != "-"){
fd := sys->open(file, Sys->OREAD);
if(fd == nil){
sys->fprint(sys->fildes(2), "cat: cannot open %s: %r\n", file);
raise "fail:bad open";
}
cat(fd, file);
}else
cat(sys->fildes(0), "<stdin>");
}
}
cat(fd: ref Sys->FD, file: string)
{
buf := array[Sys->ATOMICIO] of byte;
while((n := sys->read(fd, buf, len buf)) > 0)
if(sys->write(stdout, buf, n) < n) {
sys->fprint(sys->fildes(2), "cat: write error: %r\n");
raise "fail:write error";
}
if(n < 0) {
sys->fprint(sys->fildes(2), "cat: error reading %s: %r\n", file);
raise "fail:read error";
}
}
netbsd-cat.c
/* $NetBSD: cat.c,v 1.47 2008/07/20 00:52:39 lukem Exp $ */
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kevin Fall.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
#if !defined(lint)
__COPYRIGHT(
"@(#) Copyright (c) 1989, 1993\
The Regents of the University of California. All rights reserved.");
#if 0
static char sccsid[] = "@(#)cat.c 8.2 (Berkeley) 4/27/95";
#else
__RCSID("$NetBSD: cat.c,v 1.47 2008/07/20 00:52:39 lukem Exp $");
#endif
#endif /* not lint */
#include <sys/param.h>
#include <sys/stat.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int bflag, eflag, fflag, lflag, nflag, sflag, tflag, vflag;
int rval;
const char *filename;
int main(int, char *[]);
void cook_args(char *argv[]);
void cook_buf(FILE *);
void raw_args(char *argv[]);
void raw_cat(int);
int
main(int argc, char *argv[])
{
int ch;
struct flock stdout_lock;
setprogname(argv[0]);
(void)setlocale(LC_ALL, "");
while ((ch = getopt(argc, argv, "beflnstuv")) != -1)
switch (ch) {
case 'b':
bflag = nflag = 1; /* -b implies -n */
break;
case 'e':
eflag = vflag = 1; /* -e implies -v */
break;
case 'f':
fflag = 1;
break;
case 'l':
lflag = 1;
break;
case 'n':
nflag = 1;
break;
case 's':
sflag = 1;
break;
case 't':
tflag = vflag = 1; /* -t implies -v */
break;
case 'u':
setbuf(stdout, NULL);
break;
case 'v':
vflag = 1;
break;
default:
case '?':
(void)fprintf(stderr,
"usage: cat [-beflnstuv] [-] [file ...]\n");
exit(EXIT_FAILURE);
/* NOTREACHED */
}
argv += optind;
if (lflag) {
stdout_lock.l_len = 0;
stdout_lock.l_start = 0;
stdout_lock.l_type = F_WRLCK;
stdout_lock.l_whence = SEEK_SET;
if (fcntl(STDOUT_FILENO, F_SETLKW, &stdout_lock) == -1)
err(EXIT_FAILURE, "stdout");
}
if (bflag || eflag || nflag || sflag || tflag || vflag)
cook_args(argv);
else
raw_args(argv);
if (fclose(stdout))
err(EXIT_FAILURE, "stdout");
return (rval);
}
void
cook_args(char **argv)
{
FILE *fp;
fp = stdin;
filename = "stdin";
do {
if (*argv) {
if (!strcmp(*argv, "-"))
fp = stdin;
else if ((fp = fopen(*argv,
fflag ? "rf" : "r")) == NULL) {
warn("%s", *argv);
rval = EXIT_FAILURE;
++argv;
continue;
}
filename = *argv++;
}
cook_buf(fp);
if (fp != stdin)
(void)fclose(fp);
else
clearerr(fp);
} while (*argv);
}
void
cook_buf(FILE *fp)
{
int ch, gobble, line, prev;
line = gobble = 0;
for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) {
if (prev == '\n') {
if (ch == '\n') {
if (sflag) {
if (!gobble && nflag && !bflag)
(void)fprintf(stdout,
"%6d\t\n", ++line);
else if (!gobble && putchar(ch) == EOF)
break;
gobble = 1;
continue;
}
if (nflag) {
if (!bflag) {
(void)fprintf(stdout,
"%6d\t", ++line);
if (ferror(stdout))
break;
} else if (eflag) {
(void)fprintf(stdout,
"%6s\t", "");
if (ferror(stdout))
break;
}
}
} else if (nflag) {
(void)fprintf(stdout, "%6d\t", ++line);
if (ferror(stdout))
break;
}
}
gobble = 0;
if (ch == '\n') {
if (eflag)
if (putchar('$') == EOF)
break;
} else if (ch == '\t') {
if (tflag) {
if (putchar('^') == EOF || putchar('I') == EOF)
break;
continue;
}
} else if (vflag) {
if (!isascii(ch)) {
if (putchar('M') == EOF || putchar('-') == EOF)
break;
ch = toascii(ch);
}
if (iscntrl(ch)) {
if (putchar('^') == EOF ||
putchar(ch == '\177' ? '?' :
ch | 0100) == EOF)
break;
continue;
}
}
if (putchar(ch) == EOF)
break;
}
if (ferror(fp)) {
warn("%s", filename);
rval = EXIT_FAILURE;
clearerr(fp);
}
if (ferror(stdout))
err(EXIT_FAILURE, "stdout");
}
void
raw_args(char **argv)
{
int fd;
fd = fileno(stdin);
filename = "stdin";
do {
if (*argv) {
if (!strcmp(*argv, "-"))
fd = fileno(stdin);
else if (fflag) {
struct stat st;
fd = open(*argv, O_RDONLY|O_NONBLOCK, 0);
if (fd < 0)
goto skip;
if (fstat(fd, &st) == -1) {
close(fd);
goto skip;
}
if (!S_ISREG(st.st_mode)) {
close(fd);
warnx("%s: not a regular file", *argv);
goto skipnomsg;
}
}
else if ((fd = open(*argv, O_RDONLY, 0)) < 0) {
skip:
warn("%s", *argv);
skipnomsg:
rval = EXIT_FAILURE;
++argv;
continue;
}
filename = *argv++;
}
raw_cat(fd);
if (fd != fileno(stdin))
(void)close(fd);
} while (*argv);
}
void
raw_cat(int rfd)
{
static char *buf;
static char fb_buf[BUFSIZ];
static size_t bsize;
ssize_t nr, nw, off;
int wfd;
wfd = fileno(stdout);
if (buf == NULL) {
struct stat sbuf;
if (fstat(wfd, &sbuf) == 0 &&
sbuf.st_blksize > sizeof(fb_buf)) {
bsize = sbuf.st_blksize;
buf = malloc(bsize);
}
if (buf == NULL) {
bsize = sizeof(fb_buf);
buf = fb_buf;
}
}
while ((nr = read(rfd, buf, bsize)) > 0)
for (off = 0; nr; nr -= nw, off += nw)
if ((nw = write(wfd, buf + off, (size_t)nr)) < 0)
err(EXIT_FAILURE, "stdout");
if (nr < 0) {
warn("%s", filename);
rval = EXIT_FAILURE;
}
}
plan9-cat.c
#include <u.h>
#include <libc.h>
void
cat(int f, char *s)
{
char buf[8192];
long n;
while((n=read(f, buf, (long)sizeof buf))>0)
if(write(1, buf, n)!=n)
sysfatal("write error copying %s: %r", s);
if(n < 0)
sysfatal("error reading %s: %r", s);
}
void
main(int argc, char *argv[])
{
int f, i;
argv0 = "cat";
if(argc == 1)
cat(0, "<stdin>");
else for(i=1; i<argc; i++){
f = open(argv[i], OREAD);
if(f < 0)
sysfatal("can't open %s: %r", argv[i]);
else{
cat(f, argv[i]);
close(f);
}
}
exits(0);
}
unix2-cat.s
/ cat -- concatinate files
mov (sp)+,r5
tst (sp)+
mov $obuf,r2
cmp r5,$1
beq 3f
loop:
dec r5
ble done
mov (sp)+,r0
cmpb (r0),$'-
bne 2f
clr fin
br 3f
2:
mov r0,0f
sys open; 0:..; 0
bes loop
mov r0,fin
3:
mov fin,r0
sys read; ibuf; 512.
bes 3f
mov r0,r4
beq 3f
mov $ibuf,r3
4:
movb (r3)+,r0
jsr pc,putc
dec r4
bne 4b
br 3b
3:
mov fin,r0
beq loop
sys close
br loop
done:
sub $obuf,r2
beq 1f
mov r2,0f
mov $1,r0
sys write; obuf; 0:..
1:
sys exit
putc:
movb r0,(r2)+
cmp r2,$obuf+512.
blo 1f
mov $1,r0
sys write; obuf; 512.
mov $obuf,r2
1:
rts pc
.bss
ibuf: .=.+512.
obuf: .=.+512.
fin: .=.+2
.text
unix7-cat.c
/*
* Concatenate files.
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
char stdbuf[BUFSIZ];
main(argc, argv)
char **argv;
{
int fflg = 0;
register FILE *fi;
register c;
int dev, ino = -1;
struct stat statb;
setbuf(stdout, stdbuf);
for( ; argc>1 && argv[1][0]=='-'; argc--,argv++) {
switch(argv[1][1]) {
case 0:
break;
case 'u':
setbuf(stdout, (char *)NULL);
continue;
}
break;
}
fstat(fileno(stdout), &statb);
statb.st_mode &= S_IFMT;
if (statb.st_mode!=S_IFCHR && statb.st_mode!=S_IFBLK) {
dev = statb.st_dev;
ino = statb.st_ino;
}
if (argc < 2) {
argc = 2;
fflg++;
}
while (--argc > 0) {
if (fflg || (*++argv)[0]=='-' && (*argv)[1]=='\0')
fi = stdin;
else {
if ((fi = fopen(*argv, "r")) == NULL) {
fprintf(stderr, "cat: can't open %s\n", *argv);
continue;
}
}
fstat(fileno(fi), &statb);
if (statb.st_dev==dev && statb.st_ino==ino) {
fprintf(stderr, "cat: input %s is output\n",
fflg?"-": *argv);
fclose(fi);
continue;
}
while ((c = getc(fi)) != EOF)
putchar(c);
if (fi!=stdin)
fclose(fi);
}
return(0);
}

fork_and_forget.rb

fork_and_forget.rb
#! /usr/bin/env ruby
# "Fork and Forget"
# Don't wait if you don't have to: A mini-tutorial about concurrency
# mechanisms in Ruby and basic Unix systems programming, and how you can use
# them to avoid waiting.
#
# I have heard that people are occasionally unfamiliar with this strategy.
# It's a common idiom, regardless of language, and it is also essentially built
# into Erlang (and Termite Scheme, etc.).
#
# If you have a thing that takes forever and your program doesn't care so much
# about its output (or prefers to collect it later through some other means,
# like a pipe/file/DB/etc.), then this is probably the thing you want to do,
# rather than stopping execution to wait.
#
# The relevant methods (fork, wait, waitpid, etc.) are essentially just
# wrappers around the standard Unix system calls of the same name, and have
# almost the same semantics, although they're often nicer to use in Ruby than
# in C.
#
# Ruby:
# Process.waitpid(fork {
# do_a_thing!
# })
#
# C:
# if(pid = fork()) {
# do_a_thing();
# } else {
# waitpid(pid, NULL, 0);
# }
#
# And so, without further ado, let's get started.
require 'open-uri'
# A quick utility.
class File
def self.append fn, str
(open(fn, 'a') << str).close
end
end
# Fibonacci. The naive, recursive version is great for pegging the CPU and
# simple to implement.
def fib n
return 1 if n < 2
fib(n - 1) + fib(n - 2)
end
# We stuff the results into a file. IO.popen is another good way to grab the
# results if the current process wants to handle the data itself.
# Contrived.
def io_bound url, output
File.append output, open(url).read
end
# Contrived, way contrived.
def cpu_bound n, output
File.append output, "#{fib(n)}\n"
end
# Now we get to the interesting bits about Unix processes, Ruby threads, and
# concurrency.
# Where do processes go when they die? They become zombies. (Unix terminology
# is best terminology.) The status will show up as a "Z" in the output of
# top(1) or ps(1). The main reason they hang out like this is to allow the
# parent access to their status on exit. If the parent exits before they do,
# though, the processes become children of the init(8) process. init
# automatically reaps all of its children that become zombies.
# This is a fairly simple loop that waits to reap all of the child processes
# that have exited. They'll all run in parallel, and we'll wait until they're
# done before we continue about our own business.
def wait_for_children
# Note that, unless you pass WNOHANG (see below), Process.wait will wait
# for the processes (of course).
true while((Process.wait rescue nil))
end
# This, like the above, will reap zombies. Every time we get a SIGCLD, we try
# to reap all of the zombies we have. Signal handlers are, as far as your
# program is concerned, asynchronous (although this is a simplification), and
# when a child process dies, a SIGCLD is sent to the parent. By default, this
# signal is ignored (see the signal(7) man page), but if we set up a handler
# for it, we can reap processes when they come back.
def do_not_wait_for_children
trap('CLD') {
true while((Process.wait(-1, Process::WNOHANG) rescue nil))
}
end
# Since Ruby threads are cheap and (mostly) non-blocking, you can do something
# like this instead of a plain fork(). It spawns a thread that spawns a
# process and waits to collect that process when it exits.
def autoreap_fork(&b)
Thread.new { Process.wait(fork(&b)) }
end
# Of course, there is another option, which is to do nothing. You don't want
# to fill the process table with zombies if you are, say, a long-running
# process, but as noted above, if the parent exits, its children are adopted by
# the init process, which will reap them when they become zombies. So if
# the output of these children is collected elsewhere later, you can just exit
# after spawning them and let your OS do the rest. That's the approach we take
# here: we spawn all of the children and forget about them. When this process
# dies, our children are handled by init.
# We do some expensive calculations here. Note that this will spawn several
# processes, and fib(n) can be expensive to calculate (with the algorithm we
# use) depending on your hardware. You may want to adjust the numbers here.
# To watch output as it arrives, you can run the following in another shell
# before you start this program:
# touch /tmp/fibonacci_numbers ; tail -f /tmp/fibonacci_numbers
(1..42).each { |n|
# Note that these numbers don't necessarily arrive in order! (Although, in
# our case, it is likely that they will, since fib(n+1) will take longer to
# calculate than fib(n).
fork {
# This will make the output of top/ps a little more friendly, if you
# want to watch the processes while they run.
$0 = "fib[#{n}]"
cpu_bound n, '/tmp/fibonacci_numbers'
}
}
puts "Running a few calculations in the 'background'."
%w(
http://ruby-doc.org/core/classes/Process.html
http://debu.gs/
http://reverso.be/
http://asdf.com/
http://bigempire.com/filthy
http://gist.github.com/
http://localhost/
http://code.google.com/p/termite/
).each { |url|
# For Ruby, threads are cheaper than processes, but since they are "green"
# threads (rather than OS-level threads; JRuby is an exception here, but
# JRuby threads aren't as cheap), CPU-bound processes don't really speed up
# when parallelized with threads. Threading can also lead to odd bugs if
# the threads touch any sort of shared resource: unlike processes created
# by forking, threads share memory, file descriptors, sockets, and
# other process-level resources. Using a Thread on a problem that is not
# CPU-bound (like fetching a website from the internet, which is
# I/O-bound), though, will let all of the I/O run almost in parallel while
# we wait. Of course, forking will work here, too.
Thread.new {
io_bound url, "/tmp/#{url.gsub(/[^a-z0-9\._]+/, '_')}.html"
}
}
puts "Downloading some web pages!"
# You can use Thread#join to wait for a process to finish. I'm going to do
# this the lazy way by, instead of keeping references to the Thread objects,
# just asking Ruby for all of the threads except the current one, and joining
# those. By the time we arrive here, some of them may already be done, and
# since we didn't keep a reference around, they could have already been GC'd
# and won't show up in Thread.list.
(Thread.list - [Thread.current]).each { |thread|
# We wrap it in an exception-eater as joining a thread will give you the
# block's return value. If the thread died mysteriously, though, the
# exception that killed it will bubble up here. Since we don't especially
# care what the thread did or even if it finished its mission, but we *do*
# want to wait until all of the threads are finished before we exit (an
# arbitrary restriction; we only care for the purposes of illustrating what
# to do when you care), we join all of them but ignore any mishaps they may
# have encountered.
begin
thread.join
rescue Exception
end
}
puts "Downloaded all of them! (Or the threads crashed, or any combination.)"
# At this point, the fibonacci processes may or may not have finished
# (depending on your CPU speed versus the speed of your net connection), but
# they're no longer our problem, since this program is over.

Numbers that mean absolutely nothing.

0readme
I was waiting for a Linux kernel to build. It seems to take
longer to configure a new kernel every time, like the number
of options have been steadily increasing. I thought I might
be hallucinating, you know? Maybe I have just gotten
impatient and the bloat wasn't that bad. Or maybe it is
the case that the options have gotten horribly numerous and
increasingly arcane. In any case, I did this:
for m in $list_of_linux_machines_here; do
ssh $m wc -l '/usr/src/linux-*/.config'
done | grep -v total | sort -n | tee /tmp/kconfigs
config.wc-l is the output of that. But the results showed
different numbers for the same version (this is across
different machines, remember), and it looks to be due to
options selected. The kernel finished building before I
could figure out if there was a way to actually measure the
number of options that are presented. (How arcane they
are is inherently subjective.) So I have added more
meaningless content to the internet, and these numbers mean
nothing.
config.wc-l
3648 /usr/src/linux-2.6.32.5/.config
3801 /usr/src/linux-2.6.34.1/.config
3832 /usr/src/linux-2.6.36.2/.config
4022 /usr/src/linux-2.6.38.5/.config
4106 /usr/src/linux-3.5.4/.config
4208 /usr/src/linux-3.1.5/.config
4227 /usr/src/linux-2.6.38.5/.config
4448 /usr/src/linux-3.1.5/.config
4478 /usr/src/linux-2.6.39.3/.config
4642 /usr/src/linux-3.6.8/.config
4730 /usr/src/linux-3.1.5/.config
4838 /usr/src/linux-3.7.1/.config
5073 /usr/src/linux-3.5.4/.config

Ridiculous nonsense.

gistfile1.rb
#!/usr/bin/env ruby
# Hey, wanna see something fun?
#
# My disk broke. Thinking quickly, I decided to harness the unlimited power of
# User Error, and partially wreck my backup.
#
# Don't ask.
#
# md0 had most of the data. But the filesystem and partition table were
# wrecked, and some unknown amount of data had been exchanged between it and
# md1, thanks to hastily typed mdadm commands.
#
# No, I didn't confuse drive numbers. I said not to ask.
#
# md1 had most of the data, too. But the partitions were a different format.
# Also the first chunks of it were wrecked.
#
# sdf had a partial dd of md0. How much was a mystery to me.
#
# This script represents me, in a panic ("OH NOES MY DATA!"), dashing
# something off to determine exactly where the disks diverged and where the
# similarities were. The idea was that if I could figure out where md0 and sdf
# sync'd up and where they stopped, as well as where md0 and md1 diverged, then
# I could
#
# The variables are named by bizarre conventions, created and abandoned on the
# fly. The logic is shaky at best. Swaths were rewritten, copied and pasted
# elsewhere, or deleted. Most of the time you see a lambda, it's because I
# didn't want to name or pass function arguments. Global variables cropped up
# casually. Copy-paste was used in place of arrays. Useless optimizations
# appeared, possibly due to hallucinations. The script ran for several seconds
# and was killed and restarted as I added more hacks, more strange
# optimizations, and inane tweaks to the output.
#
# Except the comments, of which there were none originally, here is some raw,
# unedited panic code. The fevered scripting dreams of a madman.
md0 = File.open('/dev/md0')
md1 = File.open('/dev/md1')
sdf = File.open('/dev/sdf')
# The block size? Yeah, it was absolutely chosen arbitrarily.
offt = 0
bs = 4096
t0 = t1 = ts = nil
# This was so the reads would happen in parallel, and the rest of the program
# wouldn't need to stall waiting for them.
nxread = lambda {
t0 = Thread.new { md0.sysread(bs) }
t1 = Thread.new { md1.sysread(bs) }
ts = Thread.new { sdf.sysread(bs) }
}
nxread[]
# puts() et al block. This odd thread-chaining was so that, if I paused the
# output to examine it, the program would merely leak threads rather than block
# when its output buffers filled up, and so that the output would stay in
# order. It's worth noting that pt() relies on being called by only one
# thread. It spits out its pid because I was trapping USR1 at some point.
$t = Thread.new{ puts "Starting as #{Process.pid} at #{Time.now} (#{Time.now.to_i})", '_' * 80, '' }
def pt offt, &b
pt = $t
$t = Thread.new { pt.join; b.call(offt) }
end
# Yes, I have heard of queues...why do you ask?
# I don't remember why I was *this* afraid of repeating the same sprintf() more
# than once. I probably did this because I couldn't sit still while watching
# the output.
$fmtofft = Hash.new {|h,k| h[k] = ('0x%016x' % k) }
# Yes, it uses an array as a key, no, there isn't a very good reason. Don't
# ask.
$fmtstat = Hash.new { |h,k|
omd0 = []
omd1 = []
osdf = []
ls0, ls1, lsb = *k
if ls0; omd0 << 'sdf'; osdf << 'md0'; end
if ls1; omd1 << 'sdf'; osdf << 'md1'; end
if lsb; omd0 << 'md1'; omd1 << 'md0'; end
h[k] = {
:'*' => "<<md0:[#{omd0.join(',')}]>>\t<<md1:[#{omd1.join(',')}]>>",
:'0' => "md0:[#{omd0.join(',')}]\t(sdf:[#{osdf.join(',')}])",
:'1' => "md1:[#{omd1.join(',')}]\t(sdf:[#{osdf.join(',')}])",
}
}
# I don't even remember why this came out the way it did.
def pst(offt, c, s0, s1, sb)
pt(offt) { |lo|
puts "[#{c}] #{$fmtofft[lo]}: #{$fmtstat[[s0,s1,sb]][c]}"
}
end
s0, s1, sb = nil, nil, true
# This variable and the accompanying lambda, you can probably tell, were
# afterthoughts. Yes, there are two different output formats: this one and
# the one that flooded stdout. Don't ask.
changelog = {}
logc = lambda { |cof,c0,c1,cb,ls0,ls1,lsb|
lc = {}
lc[:changed] = []
lc[:md0] = []
lc[:md1] = []
lc[:sdf] = []
if c0; lc[:changed] << 'md0<=>sdf'; end
if c1; lc[:changed] << 'md1<=>sdf'; end
if cb; lc[:changed] << '[[md0<=>md1]]'; end
if ls0; lc[:md0] << :sdf; lc[:sdf] << :md0; end
if ls1; lc[:md1] << :sdf; lc[:sdf] << :md1; end
if lsb; lc[:md0] << :md1; lc[:md1] << :md0; end
changelog[$fmtofft[cof]] = lc
}
require 'pp'
loop {
# So, this pulls the last three blocks read, and then fires off the threads
# to read the next set of blocks while concerning itself with the logic.
r0 = t0.value
r1 = t1.value
rs = ts.value
nxread[]
# This code is awful. Essentially, I wanted to see when a thing started or
# stopped matching another thing.
ps0, ps1, psb = s0, s1, sb
s0 = r0 == rs
s1 = r1 == rs
sb = r0 == r1
c0 = s0 != ps0
c1 = s1 != ps1
cb = sb != psb
# Yep. Not a loop.
out = false
if c0
pst(offt, :'0', s0, s1, sb)
out = true
end
if c1
pst(offt, :'1', s0, s1, sb)
out = true
end
if cb
pst(offt, :'*', s0, s1, sb)
out = true
end
if out
logc[offt,c0,c1,cb,s0,s1,sb]
pt(offt) { |o|
puts "#{Time.now} (#{Time.now.to_i})",
sprintf(' 0x%x / %d ', o, o).center(80, '-'),
''
}
# This was originally what happened if you sent USR1, which is why it
# is a different call to pt(), with differently named variables, a
# different output format, etc. I had the idea that I'd dump state
# periodically so that I could get the script to resume if interrupted,
# but I ended up not doing that.
pt(offt) { |lo|
# It doesn't use $fmtofft. I'm sure there was a reason for this.
# Your guess is as good as mine.
lof = ('0x%016x' % lo)
sls = ''
PP.pp({
:offt => lof,
:cur => (($fmtstat[[s0, s1, sb]][:'*'] rescue nil)),
:changelog => changelog,
'$fmtstat' => $fmtstat,
}, sls)
File.open('/tmp/cmppart.stat', 'w') { |f|
f.puts sls
}
}
end
offt += bs
}
# Epilogue: I recovered my data. I am running the backup script as we speak.

Fact-checking the New Yorker

causes-icd.awk
BEGIN {
# X40-X44 is accidental overdose.
# X60-X64 is intentional (i.e., suicide)
# Y10-Y14 is unknown intent.
for(i = 0; i < 5; i++) {
cs["X4" i]++
cs["X6" i]++
cs["Y1" i]++
}
for(i in cs)
cs[i " "] = cs[i]
# X85 is homicide; not by any stretch tied to the "opioid epidemic".
# F11-F16 were phased out in 2008. They were defined as "mental and
# behavioral disorders due to psychoactive substance use", but
# overdoses were reclassified as poisoning.
# http://apps.who.int/classifications/icd10/browse/2016/en#/T36-T50
opioids["T400"]++ # Opium
opioids["T401"]++ # Heroin
opioids["T402"]++ # Codeine, morphine
opioids["T403"]++ # Methadone
opioids["T404"]++ # Pethidine, a.k.a. Demerol
opioids["T406"]++ # Other/unspecified narcotics. (Generous)
}
{
total++
age_unit = substr($0, 70, 1)
age = substr($0, 71, 3); age++;age-- # Overcome zero-padding
icd = substr($0, 146, 4)
if(age < 50 || (age_unit > 1 && age_unit < 9)) {
u50t++
if(cs[icd] && have_opioids()) {
if(icd ~ /X4/)
opioid_accident++
else if(icd ~/X6/)
opioid_intent++
opioid_total++
}
else
ocs[substr(icd, 1, 1)]++
}
}
END {
print "Causes that were not due to self-administered opioid OD:"
for(i in ocs) {
print i, "\t" ocs[i]
}
print "Total from accidental opioid overdose:", opioid_accident
print "Total from intentional opioid overdose:", opioid_intent
print "Total from opioid overdose:", opioid_total
print "Total:", u50t
print "Total, including over-50:", total
}
function have_opioids() {
return substr($0, 344, 100) ~ /T40[012346]/
}

Makefile

Makefile
# This gives you the ability to do
# git tag -a -m '1.0' 1.0
# make upload-release-1.0
# Written off the top of my head and not tested.
# Use at your own peril.
.PHONY: release
release:
mkdir -p release
.PHONY: release/HEAD.zip
release/%.zip: release
git archive --format=zip `basename $@ .zip` > $@
.PHONY: upload-release-%
upload-release-%: release/%.zip
scp $< whatever-box:/srv/http/releases/wherever
or upload it by some other means

Basic no-op version of Rack Middleware

gistfile1.txt
class SomeMiddleware
attr_accessor :app
def initialize app
# The arguments passed to use() will end up here.
self.app = app
end
def call env
# This gets called when there's a request. It
# works like a pipeline.
@app.call env
end
end

ublame

ublame
#!/usr/bin/env ruby
require 'time'
Commands = {
:git => 'git annotate %s',
:svn => 'svn blame --force %s',
}
Filters = Hash.new(lambda { |line| line })
Filters[:git] = lambda { |line|
line.force_encoding Encoding::BINARY
revision, name, time, line =
/(\w+)\s*\(([^\t]+)\t([^\t]+)\t[^\)]+\)(.*)/.match(line).to_a[1..-1]
time = Time.parse time
"%s %s %10s | %s\n" % [
revision, time.strftime('%F %R'), name[0,10], line
]
}
files = ARGV.dup #.map { |a| File.expand_path a }
noexist = files.select { |f| !File.exist?(f) }
unless noexist.empty?
$stderr.puts "Fictitious files passed as args:\n\t#{noexist.join(' ')}"
exit 1
end
def figure_out_repotype path = Dir.pwd
while path != '/'
if File.directory?(File.join(path, ".git"))
return :git
elsif File.directory?(File.join(path, ".svn"))
return :svn
end
path = File.dirname path
end
$stderr.puts "Couldn't figure out what sort of repo this is!"
exit 2
end
type = figure_out_repotype
command = Commands[type]
files.each { |f|
print *IO.popen(command % f, 'r').readlines.map(&Filters[type])
}

See 0README. Power management.

0README
These change the background color in X (and I think they don't work if you are
using a desktop system, so the `xset` command ought to be changed for whatever
Gnome/KDE/LXDE/XFCE/ASDFJKLSEMICOLON thing you are using if you are using such a
thing) based on battery power remaining. The Lua one requires luaposix to be
installed.
The reason there are two versions is that Ruby was, when it ought to have been
sleeping, doing some select() loop. I figured Lua would not do that to me, and
it does not. (Porting is usually more fun than fighting the language.)
These are dirty scripts. The Ruby one in particular. It was written way back
in 2008 and occasionally patched. They are not particularly well-designed,
either internally or from a usability perspective. You've been warned.
power.lua
#!/usr/bin/env lua
colors = {
red = {min = 99, max = 30},
green = {min = 10, max = 99},
blue = {min = 10, max = 99}
}
fcache = {}
battery_path = io.popen('ls -d /proc/acpi/battery/BAT*/ | sed 1q'):lines()()
function cstr(t, frac)
return string.format("%d", t.min + ((t.max - t.min) * frac))
end
function cmd(frac)
return "xsetroot -solid rgb:" ..
cstr(colors.red, frac) .. "/" ..
cstr(colors.green, frac) .. "/" ..
cstr(colors.blue, frac)
end
function pull_state()
local state = {}
for i, fname in pairs({"alarm", "info", "state"}) do
for line in io.lines(battery_path .. fname) do
local colon = string.find(line, ":")
local n = string.find(line, "%d")
if colon and n then
local key = string.sub(line, 1, colon -1)
local val = tonumber(string.match(line, "%d+"))
if key == "present rate" then state.rate = val
elseif key == "last full capacity" then state.capacity = val
elseif key == "remaining capacity" then state.present = val end
end
end
end
state.plugged_in = state.rate == 0
state.pct = (state.present * 100) / state.capacity
return state
end
function set_color()
local state = pull_state()
local fraction = math.floor(state.pct)
if not fcache[fraction] then fcache[fraction] = cmd(state.pct / 100) end
os.execute(fcache[fraction])
end
if arg[1] == "-bg" then
set_color()
elseif arg[1] == "-d" then
local p = require("posix")
local pid = p.fork()
if pid == 0 then
p.chdir("/")
devnull = p.open("/dev/null", p.O_RDWR)
p.dup2(devnull, 0)
p.dup2(devnull, 1)
p.dup2(devnull, 2)
pid = p.fork()
if pid == 0 then
while true do
set_color()
p.sleep(61)
end
else
os.exit(0)
end
else
os.exit(0)
end
else
local state = pull_state()
local rem = state.present / state.rate
local hls
if state.plugged_in then hls = "(plugged in)"
else hls = string.format("(%0.02f hours remaining)", rem) end
print(string.format("%6.02f%% ", state.pct) .. hls)
end
power.rb
#!/usr/bin/env ruby
Colors = {
:red => [99, 30],
:blue => [10, 99],
:green => [10, 99],
}
FCache = []
BatteryPath = Dir['/proc/acpi/battery/BAT*/'].first
def ccalc(min, max, fraction)
min + ((max - min) * fraction)
end
def pull_state
bat_info = []
%w(alarm info state).each { |file|
bat_info.concat File.readlines(BatteryPath + file)
}
bat_info.map! { |line| line.split(':').each { |i| i.strip! } }
pbi = Hash.new { |h,k| h[k] = bat_info.assoc(k).last }
state = {
:rate => pbi['present rate'].to_i,
:capacity => pbi['last full capacity'].to_i,
:present => pbi['remaining capacity'].to_i,
}
state[:plugged_in] = state[:rate].zero?
state
end
def set_color
state = pull_state
fraction = (state[:present] * 100) / state[:capacity]
FCache[fraction] ||= begin
f = fraction.to_f / 100
'xsetroot -solid rgb:%d/%d/%d' % [:red, :green, :blue].map! { |c|
ccalc(Colors[c].first, Colors[c].last, f)
}
end
system(FCache[fraction])
end
case ARGV.first
when nil
state = pull_state
fullness = (state[:present] * 100.0) / state[:capacity]
hours_left = state[:present].to_f / state[:rate]
hlstring = if state[:plugged_in]
"plugged in"
else
sprintf "%0.2f hours remaining", hours_left
end
printf "%6.02f%% (#{hlstring})\n", fullness
when '-bg'
set_color
when '-d'
fork {
Dir.chdir '/'
fork { loop { set_color; sleep 61 } }
}
end

"tac", ported to Limbo as an example.

tac.b
implement Tac;
include "sys.m"; sys: Sys;
include "bufio.m"; bufio: Bufio; Iobuf: import bufio;
include "draw.m";
Tac: module {
init: fn(nil: ref Draw->Context, args: list of string);
};
stdout: ref Sys->FD;
init(nil: ref Draw->Context, args: list of string)
{
sys = load Sys Sys->PATH;
bufio = load Bufio Bufio->PATH;
stdout = sys->fildes(1);
args = tl args;
if(args == nil)
args = "-" :: nil;
for(; args != nil; args = tl args) {
file := hd args;
if(file != "-") {
fd := sys->open(file, Sys->OREAD);
if(fd == nil){
sys->fprint(sys->fildes(2), "tac: cannot open %s: %r\n", file);
raise "fail:bad open";
}
tac(fd, file);
} else {
tac(sys->fildes(0), "<stdin>");
}
}
}
tac(fd: ref Sys->FD, file: string)
{
lines: list of string = nil;
line: string;
fio := bufio->fopen(fd, bufio->OREAD);
if(fio == nil) {
sys->fprint(sys->fildes(2), "tac: Couldn't create a bufio for %s: %r\n", file);
raise "fail:bufio";
}
while((line = fio.gets('\n')) != nil)
lines = line :: lines;
while(lines != nil) {
buf := array of byte (hd lines);
sys->write(stdout, buf, len buf);
lines = tl lines;
}
}

gist:2046785

gistfile1.txt
#!/bin/sh
dropdb thedb
createdb thedb
ssh root@host5 /usr/local/pgsql/bin/pg_dump \
gzip -c \| \
tee prod.db.gz | \
gunzip | \
tee prod-without-audits.sql | \
psql thedb
psql thedb < prod.db.audit_schema

JSON pretty-printer. Not sophisticated.

jsonpp
#! /usr/bin/env ruby
require 'json'
require 'pp'
mode = :ruby
ARGV.each_with_index { |arg, i|
next unless arg.start_with? ?-
ARGV.delete_at i
case arg
when '-j'
mode = :json
when '-r'
mode = :ruby
when '--'
break
else
$stderr.puts "Un-understood option: #{arg}"
break
end
}
content = ARGF.read
parsed =
begin
JSON.parse content
rescue JSON::ParserError => e
$stderr.puts e.inspect
mode = :nop
content
end
case mode
when :nop
print parsed
when :ruby
pp parsed
when :json
puts JSON.pretty_unparse(parsed)
end

A dude has posed a question: https://mobile.twitter.com/djdonnell/status/121375620440670208

0README
The "/" has to be there before rack even gets to it; you cant do a GET without a path of some sort.
with-slash
pete@aku:~$ echo -ne 'GET / HTTP/1.0\r\n\r\n' | netcat localhost 80
HTTP/1.0 200 OK
[elided]
without-slash
pete@aku:~$ echo -ne 'GET HTTP/1.0\r\n\r\n' | netcat localhost 80
HTTP/1.0 400 Bad Request
Content-Type: text/html
Content-Length: 349
Connection: close
Date: Wed, 05 Oct 2011 03:05:54 GMT
Server: lighttpd/1.4.28
[elided]

Metabolic Fascism!

gistfile1.txt
From Olin Shivers's "opinion file", a collection of posts from the "Opinion
Bboard" at CMU ( http://www.ccs.neu.edu/home/shivers/opinion.html ):
17-May-89 12:18 Hans.Tallis@ML metabolic fascism
Article 106 of ics.whimsey:
>From: David A Honig <honig@BONNIE.ICS.UCI.EDU>
Subject: Metabolic Fascism
Lines: 144
------------------------------------------------------------------------
Metabolic Fascism
=================
by Basil Hosmer
Every programmer has some experience with bodily abuse. Sooner or
later, all of us do things to ourselves we wouldn't admit to Mom. Most
of the time we say we're provoked by circumstances: whether it's the
representative from your client's company -- a not pleasant man who
looks a lot like Herman Munster, breathing heavily on your neck -- or
some towering, unstoppable endorphin rush that threatens to rip your
medulla out of its socket if you don't code up that monstro algorithm
RIGHT NOW and forget about your wedding. We generally attribute our
protracted binges to some external force.
This attitude bespeaks a hideous wrong-headedness among programmers. We
seem to get some masochistic pleasure out of responding to pressure by
sitting in front of our machines until our fingernails are too long to
type. Our eyes get varicose veins. We run fingers through our hair
until we get split ends. We drool. Why?
Because, the deluded among us would answer, we have to. Some specter is
chaining us to our chairs, making strangers of our families, removing us
from the throb of humanity. It's not a pretty job, we sigh nobly, but
someone has to do it. This is, as my sister used to say, pompous fudge-
cakes. We do it because we like it.
In view of this, I submit a philosophy of life which has served me well
for the past couple of years. I call it Metabolic Fascism.
There are several basic tenets to this philosophy, but one provides the
foundation for the rest: You Are At War With Your Body.
Picture a table. A lobbyist for your brain sits on one side, a lobbyist
for your body on the other. They are pushing their respective interests
as you go through your life. In a democratic regime, one might overhear
something like this during a normal day:
BODY: Nothing like a good, hearty breakfast to kick-start the day.
BRAIN: Yeah...I feel some serious creativity coming on. It's gonna be a
banner day for original thought. Can we arrange a little rush
from a relevant gland to start things off?
BODY: Why, sure. (Drains a mug of java...) There we go.
BRAIN: Thanks.
(Some eight hours later.)
BODY: Okay, it's about time to wind things down.
BRAIN: But...
BODY: C'mon, it'll be better in the morning if we quit now.
BRAIN: Aw, okay.
(After some interval, sleep, then repeat cycle.)
Now, this has its obvious advantages. Brain and body maintain a working
camaraderie, the cycle of ups and downs is never too extreme or debili-
tating, and the productivity of the two working in tandem is fairly
consistent and predictable.
On the other hand, come the day when Herman Munster is breathing down
your neck, you might HAVE to trash that comfy little system for some-
thing a little more, well, authoritarian. My solution is simple:
metabolic fascism. Not when you have to crank it out, but ALL the time.
To wit:
BODY: Not coffee AGAIN.
BRAIN: You don't want it, throw it up. But don't bother me. Have some
dessert.
BODY: Lucky Strikes a la carte. Delectable. My lungs look like Fire-
stones.
BRAIN: Listen. I'm on the verge of a universe-tilting breakthrough. I
don't need your sniveling.
BODY: Are we gonna get some sleep this week?
BRAIN: Yeah, yeah.
(Some 14 hours later.)
BODY: Look, man, I'm gonna die here. I wanna go to bed.
BRAIN: SILENCE!
(Rains vicious blows upon the Body Lobbyist until he sinks beneath the
table, a simpering lump of protoplasm.)
Philistine.
(Some 10 hours later, the Body Lobbyist has risen from beneath the
table, wearing full body armor and a catcher's mask.)
BODY: Sleep. Now.
(The Brain lobbyist produces a dreadnought Louisville Slugger, festooned
with nails, and clubs the Body Lobbyist senseless.)
BRAIN: Where was I?
(Some eight hours later, the Body Lobbyist rises and leaves the room.
The Brain Lobbyist, deep in some amphetamine-induced trance, fails to
notice. Several minutes later the Body Lobbyist re-enters, carrying a
bazooka. He liberally distributes the Brain Lobbyist about the room.)
BODY: Sleep. Now.
(Perhaps 20 hours later, another Brain Lobbyist enters the room. Repeat
cycle.)
There are tradeoffs to this methodology, sure. But the advantages are
overwhelming.
First, it's more honest. After all, the first time a deadline or a good
idea rolls around, you're gonna shaft your body anyway, right? Why not
accustom yourself to those inevitable caffeine fests BEFORE they descend
on your unsuspecting, pampered physiognomy?
Second, there is no better way to accumulate a comprehensive, detailed
knowledge of one's body than by abusing it regularly. Whereas most
humans can only recognize vague, ambiguous bodily states and apply
almost meaningless words like "good," "bad," "tired" and "rested" to the
way they feel, a metabolic fascist becomes sensitive to the most subtle
changes in his system. He learns to check his pulse by noting the fre-
quency of the shaking in his hands. He learns to check his blood
pressure by gauging the accuracy with which he hits the reboot switch.
To a metabolic fascist, the body is a finely-tuned machine operating
somewhere past the ragged edge. One pays much more attention to an
engine about to explode than to one that is idling, and a metabolic fas-
cist knows his body to a degree of detail that, among other humans, only
long-distance runners and new mothers achieve.
(Not to mention the fact that this mode of living produces a certain
manic look about the eyes that is useful for everything from terrifying
muggers to staring down that fossilized waitress who never, EVER, takes
back a cheeseburger because it's too well- done.)
The peripheral benefits are legion. When was the last time you really
wondered what day it was? A genuine scratch-your-head-and-call-up-
Sidekick kind of puzzlement? When was the last time you were truly
surprised that the sun decided to rise? When was the last time you
stared, entranced, as the sort routine you just wrote turned into little
green soldiers that danced across your screen? To the metabolic fascist,
life once more becomes that fascinating, unpredictable thing most humans
never see after they graduate from diapers.

Twitter 1x1 tracking gif URLs

0README
I was looking at the traffic New Twitter was sending across, having
opened Firebug to see just how wide the content was (too wide for my
848px-wide phone at 920px). I kept seeing 1x1 transparent .gifs, which
all True Patriots have been at war with since the 90s, so I was curious
as to what they were doing in there. There was nothing interesting in
the headers (except the expected six or so different ways to instruct
all browsers everywhere to not cache the content), but the URLs are
huge.
As far as I can tell from the five or six URLs I looked at, it's just
analytics data. There seems to be no harm in doing `echo
255.255.255.255 scribe.twitter.com >> /etc/hosts`, so I did that on the
machine that runs dnsmasq for the home network.
decode.rb
#! /usr/bin/env ruby
# Reads Twitter tracking links from stdin, spits out some pretty-printed JSON.
# Much more readable. If you want to try it out, cloning the repo and doing
# "./decode.rb < example-links" will run it on the links that I had, or you
# could paste the scribe.twitter.com URLs you find.
require 'uri'
require 'cgi'
require 'json'
loop {
(print "link: "; $stdout.flush) if $stdout.tty?
link = gets.chomp rescue exit
next if link.empty?
# This is probably fragile, but works for me as of 2011/08/06:
begin
puts JSON.pretty_unparse(
JSON.parse(CGI.parse(URI.parse(link).query)['log[]'][0]))
rescue
$stderr.puts "Couldn't recognize #{link}."
end
}
example-links
first-link-decoded.json

Awk script to install Ruby.