The Boston Diaries

The ongoing saga of a programmer who doesn't live in Boston, nor does he even like Boston, but yet named his weblog/journal “The Boston Diaries.”

Go figure.

Saturday, April 01, 2006

Arlo Lipof's Gold

I was searching through my (physical) files when I came across this letter I found in a library book twenty years or so ago. It's not a complete letter—it appears to be from the second page and it included a hand drawn diagram.

On its surface, the [Banach-Tarski] paradox resembles the well-known puzzle involving tangrams, little pieces of paper cut into simple geometric shapes. Four such shapes can be assembled into a square that has an area of 64 square inches. Yet the very same pieces can also be assembled into a rectangle that has a greater area—65 square inches, to be precise. If you do not believe such a thing is possible, try cutting up the pieces as shown in my drawing.

If the little pieces of paper were instead pieces of gold, there would seem to be an automatic increase in wealth in going from the square to the rectangular configuration. Start with a square of gold, say, eight inches on a side and an inch thick. Then cut it according to the first figure. If the pieces are reassembled according to the second figure, an extra cubic inch of gold will have appeared. The extra cube would weigh approximately 4.3 ounces and at current prices would be worth about $160.

[64 square units, with specific cuts]
[65 square units, with specific rearrangement]

It goes on from there in increasingly dense prose and mathematics and it's signed “Arlo Lipof,” whom I never heard of, nor could I find any information about him at the time (nor can I even today).

Like I said, I found this some twenty years ago but there's no telling how old the actual letter is. I mean, I could figure out when gold was last $35 an ounce, but that still wouldn't tell me anything about the letter.

I remember my amazement at the time, to find such an incredible means of generating wealth, but being unable to even act upon it. I mean, here I am, a teenager. What was I going to do? Go to my parents? “Yeah, can I borrow a fifty thousand dollars? I want to buy 64 ounces of gold.” Like that would happen. Besides, where would one even buy bars of gold? Can one even buy gold bullion?

So the paper was filed away and forgotten.

But now that I'm an adult, it should be easier for me to get gold. Let's see … 64 cubic inches … 4.3 ounces per cubic inch … $580 an ounce … $159,616.00! Ouch!

Wonder if I can get a second mortgage on Casa New Jersey?

Sunday, April 02, 2006

“I'm fooling you and you don't like it!”

Biggest reaction yet to an April Fool's LayoutSpring liked it, Bunny (who does not have a website as far as I know, but she sent email, and yes, that's her real name) didn't care for it, and Mike had problems viewing it correctly, which I suspected as much, given the rigidity of the layout (any window less than 900 pixels across and the layout would be screwed up).

This years theme was drawing paper and the graphics were ones I stole from another blog (and I lost the link—sorry). I liked the look, but it proved to be less flexible for layouts than I wanted. It was an interesting experiment in CSS, and if you are using Mozilla or Firefox you can view this year's April Fool's layout (or the past ones I've done) by going to the menu and selecting “View → Page Style”.


Now, about Arlo Lipof's gold …

Yesterday I posted about cutting a square of gold in such a way that when reassembled, it appeared that you get more gold than you started with, and that it's related to the Banach-Tarski Paradox (which is a real mathematical theorm by the way).

I'm sorry to say that the cuts suggested won't generate any more gold (least everybody would be doing it and the price of gold wouldn't be anywhere near $585 an ounce (up $5 since yesterday I see). The Banach-Tarski Paradox works on mathematical cows, not real world matter. Had one actually cut gold as specified, you would still end up with 64 cubic inches of gold, with a slender 1 cubic inch gap in the middle. I remember as a kid spending a few hours proving that to myself (lots of algebra, slops, Y-intercepts, area of triangles, that type of stuff, all on a sheet of graph paper) because, you know, I wanted to make sure before asking the 'rents for $50,000.

Boy, talk about disappointing.

Monday, April 03, 2006

It'll never happen again, unless it does happen again …

From: Dad <XXXXXXXXXXXXXXXXXX>
To: The Kid <sean@conman.org>
Subject: SOMETHING THAT WILL NEVER HAPPEN AGAIN …
Date: Mon, 3 Apr 2006 03:02:06 EDT

On Wednesday of next week,

at two minutes and three seconds after 1:00
in the morning,
the time and date will be
01:02:03 04/05/06!

That won't ever happen again.

Hate to say this Dad, but it will happen again, next month, in Europe, when it will be 01:02:03 04/05/06 (they print dates DD/MM/YY instead of this crazy backwards US way of MM/DD/YY).

Also, according to Mark Evanier, it'll happen once a century and for those of you using non-military time, it'll happen twice!

Tuesday, April 04, 2006

What a slacker

I just found out that Smirk is in the hospital. He's been pretty sick for the past few weeks and was out of the office all last week, so it's not terribly surprising he's there.

On the plus side—he didn't swallow any magnets.

Update later today

After visiting him in the hospital, he sounded much better than he did on the phone. And he's only expecting to stay there for a few days, thankfully.

Wednesday, April 05, 2006

Failed to get the memo

So I'm still working with Lisp Scheme guile, and I'm still questioning if Lisp Scheme guile is a HLL or a HHL-wannabe.

I'm at a point where using a structure would be the best thing to use. A structure is nothing more than a collection of data (possibly of different types) that can be treated as a unit. In C, a typical structure definition would be (example from my own code):

/* data associated with a web-request */

struct http
{
  URLHTTP url;
  List    headers;
  Stream  io[2];
  int     version;
  int     status;
};

Pretty straight forward.

I check the the documentation and yes, it supports structures.

Cool!

So, here's how you define a “simple” structure with only two elements:

(define ball-root (make-vtable-vtable "pr" 0))
          
(define (make-ball-type ball-color)
  (make-struct ball-root 0
	       (make-struct-layout "pw")
               (lambda (ball port)
	         (format port "#<a ~A ball owned by ~A>"
                         (color ball)
                         (owner ball)))
               ball-color))
        (color ball) (struct-ref (struct-vtable ball) vtable-offset-user))
        (owner ball) (struct-ref ball 0))

What? Did Lisp Scheme guile take lessons from Forth? I have to manually construct the structures? This is a HLL? And not only do I have to write code to create structures, but I also have to write code to populate them. Anyone remember BASIC?

10 DIM A(20):FOR I=1 TO 20:READ A(I):NEXT I
20 DATA 3,4,23,88,2,3,4,9,10,12,44,87,8,7,6,13,33,8,29,0

(Which, incidentally, is another pet-peeve of scripting languages—the inability to have pre-initialized data at run time.)

I suppose I could always write code to make structures easier, but why should I have to abstraction to what is arguably the highest level programming language in existance? (although structures might be easier to use in Common Lisp, I don't have a Common Lisp environment to test it) Have structures fallen out of vogue in HLLs? Did I fail to get the memo?

Thursday, April 06, 2006

… 1500 webpages be reviewed for futher understanding and contextual perspective of the primary documents presented.

For academics, researchers, students and others who may wish to get to the “gist of the matter” immediately, there is a SHORTCUT MENU to the Primary Documents on this website located just below on this Opening Page. It is, however, recommended that the entire website's 1500+ webpages be reviewed for further understanding and contextual perspective of the primary documents presented.

The OPENING PAGE: QUFD: Einstein's Legacy!

I just love Crank Dot Net, a site that links to a slew of crankpot websites, tags them (the one above is tagged “grand unification,” “quantum mechanics,” “philosophy,” “consciousness,” “new age” and “religion”) and ranks them (the above: “crankiest”).

What caught me above was the bit about reviewing the 1500+ pages to understand what the site is about, but the site as a whole only ranks as “crankiest.” The best sites are those labeled “illucid” (and yes, the site being linked is … well … the individual words are in English but I can't quite say I understand what they mean in conjunction with each other, which pretty much defines the word “illucid”).

1500 pages.

Heh.

Friday, April 07, 2006

I think I love New Hampshire

[Art.] 10. [Right of Revolution.] Government being instituted for the common benefit, protection, and security, of the whole community, and not for the private interest or emolument of any one man, family, or class of men; therefore, whenever the ends of government are perverted, and public liberty manifestly endangered, and all other means of redress are ineffectual, the people may, and of right ought to reform the old, or establish a new government. The doctrine of nonresistance against arbitrary power, and oppression, is absurd, slavish, and destructive of the good and happiness of mankind.

Via Fans of the Adventures of Brigadier General John Stark, New Hampshire State Constitution, Article 10

If one had to change the wording on the Second Amendment of the United States Constitution, this is what should replace it. And if you think I'm a crazed radical for thinking such thoughts, then I'm in good company (“God forbid we should ever be 20 years without such a rebellion … What country can preserve its liberties if rulers are not warned from time to time that their people preserve the spirit of resistance?” –Thomas Jefferson, author of the Declaration of Independence and the Third President of the United States; he's also quoted as saying, “I hold it that a little rebellion now and then is a good thing, and as necessary in the political world as storms in the physical. Unsuccessful rebellions, indeed, generally establish the encroachments on the rights of the people which have produced them. An observation of this truth should render honest republican governors so mild in their punishment of rebellions as not to discourage them too much. It is a medicine necessary for the sound health of government.”)

Perhaps a move to New Hampshire is in order?

Saturday, April 08, 2006

I think Forth is a higher level language than Lisp

The preceding chapter discussed the list, Lisp's most versatile data structure. This chapter show how to use Lisp's other data structures: arrays (including vectors and arrays), structures, and hash tables. They may not be as flexible as lists, but they can make access faster, and take up less space.

Chapter 4, ANSI Common Lisp

I'm tempted to read that paragraph as:

The preceding chapter discussed the list, Lisp's most versatile only data structure. This chapter show how to use Lisp's other badly implemented data structures: arrays (including vectors and arrays), structures, and hash tables. They may not be as flexible slow as lists, but they can make access faster and at the same time, more tedious, and take up less space.

Chapter 4, ANSI Common Lisp

But I'm better than that.

Yes, structures in Common Lisp are a bit easier than in guile:

(defstruct foo
	x
	y)

You have the name of the structure and each field. The (defstruct) function, however, will go ahead and make several functions for you to help “manage” the structure, such as (make-foo), (foo-p) (foo-x) and (foo-y).

Yes, by declaring a structure, one ends up with a function per field, plus two additional functions. So one goes:

(defstruct foo
	x
	y)

(setf a (make-foo))
(setf (foo-x a) 42)
(setf (foo-y a) 12)

Which to me doesn't make any sense. And to describe why it doesn't make sense, I have to go into some depth about Common Lisp symbols. A symbol in Common Lisp is what most people would consider a name. In (setf x 42) both setf and x are symbols. But internally symbols are just more than a name. Way more.

A symbol is also a type unto itself in Common Lisp (as in Scheme, but there, they're way simpler) and contain more than just its name:

Layout of the Common Lisp Symbol foo
Name foo
Value 42
Function(some internal pointer to code)

There are a few other fields, like which package it's in, and property lists (a series of name/value pairs, much like Common Lisp's associated lists, but aren't stored or implemented as associated lists—go figure) that aren't germane to this discussion, so they're left out.

But notice that each symbol has both a “function” and a “value.” That means one can define setf to have a value, like:

(setq setf 42)

A parenthetical aside: “But wait a second,” you say, “didn't you use (setf) above to set the value?” Yes, but one can also use (setq) to make sure one sets the “value” of a symbol to a given value. (setf) is now preferred over (setq) because it's more generalized:

(setf {place value}*

A generalization of setq: stores in the locaiton associated with each place the value of the corresponding value expression. If a value expression refers to one of the preceding places, it will get the new value. Returns the value of the last value.

A valid place expression may be: a variable; a call to any function designated here as “settable” so long as the relevant argument is a valid place; a call to apply whose first argument is #'aref, #'bit, or #'sbit; a call to an accessor function defined by defstruct; a the or values expression in which the argument(s) are valid places; a call to an operator for which a setf expansion has been defined; or a macro call that expands into any of the preceding.

Hey! I didn't write this crazy language! And thus ends the parenthetical aside.

Now, given that each symbol can have both code and data associated with it, why one couldn't have done:

(defstruct foo
	x
	y)

(foo a)
(setf (a x) 42)
(setf (a y) 12)

Something like that is the first think a programmer in Forth (yet another language where one has to implement common data structures by hand, yet it never claimed to be a HLL to begin with, and one can write a Forth compiler in about 1k of code, so it's a very simple langauge).

But no, we get a profusion of “special functions” created for each structure. And heaven help you if you create a structure with a field named “p”!

Oh, what does (foo-p) do?

By Common Lisp convention, functions that end in “p” or “-p” are queries, such as (string-greaterp) (is one string greater than another?) or (equalp) (one of the five or so equality functions) or (complexp) (is a value a complex number?) so in this case, (foo-p) is asking if the value is a structure of type foo (and since I don't have a Common Lisp environment, I can't see what happens if one does create a structure with a field named “p”).

Yeah, I'm really begining to agree with John McCarthy about Lisp.


American Splendor

I just watched American Splendor, a biography of Harvey Pekar, writer of the comic book American Splendor which chronicles his life as a file clerk (and he remained a file clerk while writing the comic—I guess you could say he was a blogger before blogging was invented, using comics as his vehicle instead of a huge ever growing pulsating webpage that rules from the center of cyberspace).

The movie wasn't a documentary. I think.

I mean, it starred Paul Giamatti as Harvey, and Hope Davis as his third wife, Joyce, but it was narrated by Harvey Pekar (who commented that Paul Giamatti doesn't look anything like him), and had interviews with both him and his wife, and even some commentary from Harvey's friend Toby Radloff (played by Judah Friedlander in the film).

A real mind-bending scene was when Harvey (as played by Giamatti) and Joyce (played by Davis) went to the opening of a play based upon the comic book (which is based upon the life of Harvey)—so Harvey is providing narration, we're watching Giamatti and Davis (portraying Harvey and Joyce) watching Donal Logue and Molly Shannon playing Harvey and Davis.

It was probably the most self-referential film I've ever seen.

Overall, it was a good film (Spring was expecting to suffer through watching it, but ended up enjoying it) and a very unique way of handling the subject matter.

Sunday, April 09, 2006

Editing text on a webpage

This demonstration of a web-based editor (link via DECAFBAD) looked promising and the instructions for including it withing a webpage were easy enough that I decided to give it go.

Turns out I don't really care for it that much, as it doesn't suit my style of writing on the web. The HTML it more WYSIWYG than structural, and I write structural HTML. I suppose I could modify the code (written in JavaScript) to make it more my liking, but I'm not up to slogging through 60,000 lines of JavaScript to fix a few problems for something I may end up using.

It might, however, make editing of existing entries pretty sweet, to fix typos and word choice from within the browser instead of the method I use now (which involves logging onto the webserver and editing the raw entry in an editor). I might have to try that.

Monday, April 10, 2006

IN-bloody-SANE

Ticket in the support queue: “Hey, can't check my email since my account is overquota!”

Hey, I think someone clued in enough to know what the actual problem is! Wonderful! Okay, it's not wonderful that he's overquota due to spam, but it is wonderful because it's more than just “the Intarweb is broke!”

I log into the server, check his mail spool files. Yup, a couple of mailboxes are over 100M in size; one is over 200M. I run a script (which I wrote) that moves the spool file to a backup (and changes ownership of the spool so the space doesn't count against the customer) and creates an empty spool file. The backup is so that if there were any legitimate email (which, frankly, isn't likely in most cases, since these mailboxes are often not checked by the customers since they are unaware of the existance of said mailboxes, or forgot, or just don't care) we can retrieve them if necessary. So I run the script on the largest spool file.

After it runs, I check. 12K spool file, when it should be 0K. Check again. 42K. Check again, 63K. The spam is just pouring in. I check through the <shudder> control panel and yes, unless specified otherwise, all email for the customer's domain will end up in this mailbox. I change it to /dev/null (the bit bucket) and check back with the spool file. 1.5M, less than two minutes.

Now, perhaps over an hour later, the spool file is 22M in size, and apparently, setting this mailbox to /dev/null in the <shudder> control panel didn't work. I may have to link the spool file to /dev/null myself.

Tuesday, April 11, 2006

There's gold in them thar art stores!

So I'm reading a sales flyer for an art supply store when I see they're selling books of gold leaf, normally $80.00 for the low, low price of $18.99.

Wait a second!

They're selling 23.5kt gold for ¼ the normal price‽ Are they insane?

I'm planning on running down to the store as soon as it opens and snapping up as much gold leaf as I can, what with gold breaking the $600/ounce, then selling it to make a 400% profit when sanity smacks me over the head. I had better figure out how much gold is in a typical book of gold leaf before I loose my shirt on a half-cocked scheme.

Some Google searches and I learn that gold leaf is sold in “books” of 25 leaves, or “boxes” of 500 leaves, and that there is anywhere from 15–23 grams of gold per 1000 leaves. Okay, but this is the United States, where we buy and sell using the archaic Troy ounces for metal. Another search reveals 31.103477 grams per Troy ounce. So, 600 (latest price I have is $601.50 per ounce) divided by 31.103477 gives us $19.29 per gram. Let's be optimistic here and say we have “heavy” gold leaf (23 grams per 1000 leaves) … 23 divided by 1000 (giving us the gold per leaf) times 25 (number of leaves per “book”) times 19.29 give us … $11.09 worth of gold per book.

THAT'S IT‽

Maybe $10 worth of gold?

And this normally sells for $80?

What a racket!

Ah well … so much for gold fever.


We could have done that

Via YARGB are some interesting password recovery times based upon password content, length and type of computing resources one has.

I remember back in college (in the early 90s) we had access to a MasPar with, I think, 4,096 processing nodes. There was talk of writing a password cracking program for the machine, which was a perfect use for the machine, being a SIMD architecture (same program on each processing node, but different data). The default Unix password scheme (at the time) used a 12 bit number to “randomize” the password, so there could be 4,096 different encryption results for any given password. A perfect fit for the MasPar—instead of having to do 4,096 serial encryptions of a guess, all 4,096 possible values could be tested at once. An incredible increase in speed (it could do in an hour what it would take a conventional computer about 24 days to do).

But alas, we never got around to it; I'm suspect it was because no one really wanted to program in FORTRAN.

Wednesday, April 12, 2006

“I … am not left handed.”

Ouch.

I hurt.

The Kids have boffers, practice swords made of PVC pipe, padding and duct tape which they made with help from a friend of Spring's who's in the SCA.

When I got home yesterday, they were outside practicing sword fighting and asked if I wanted to try it out.

I admit it was fun, but all the running, lunging and swinging has left me rather sore.


Death and Taxes

Ouch.

I hurt.

I did my taxes last night.

Let me just say that Schedule SE just plain sucks. Getting hit with 7% Social Security as an employee and 7% as an employer really hurts. Especially given that as an employer I can't write off the 7% as a business expense in this case.

Thursday, April 13, 2006

Leaky abstractions at hot spots

Wlofie mention clive, a C-based Live Journal client, was vastly slower than jlj, a Perl based Live Journal client. Having encountered some weirdness in the past like this, I thought it might be fun to profile the code and see where the problem might lie.

Results of profiling
% time cumulative seconds self seconds calls self µs/call total µs/call name
% time cumulative seconds self seconds calls self µs/call total µs/call name
73.33 0.11 0.11 3693 29.79 29.79 getalloc
6.67 0.12 0.01 18630 0.54 0.54 lj_debug
6.67 0.13 0.01 3323 3.01 3.55 hash
6.67 0.14 0.01 1483 6.74 10.78 getp
6.67 0.15 0.01 4 2500.00 34335.39 delete_hash
0.00 0.15 0.00 3693 0.00 29.79 lj_free
0.00 0.15 0.00 1841 0.00 0.00 chomp
0.00 0.15 0.00 941 0.00 10.78 get
0.00 0.15 0.00 936 0.00 0.00 grow_alloctable
0.00 0.15 0.00 936 0.00 0.54 lj_malloc
0.00 0.15 0.00 936 0.00 0.00 newalloc
0.00 0.15 0.00 924 0.00 1.07 next
0.00 0.15 0.00 920 0.00 137.20 del
0.00 0.15 0.00 920 0.00 6.23 put
0.00 0.15 0.00 12 0.00 0.00 MD5Update
0.00 0.15 0.00 11 0.00 35.15 geti
0.00 0.15 0.00 11 0.00 35.15 getpi
0.00 0.15 0.00 7 0.00 0.38 lj_set_config
0.00 0.15 0.00 6 0.00 0.00 MD5Transform
0.00 0.15 0.00 4 0.00 0.00 MD5Data
0.00 0.15 0.00 4 0.00 0.00 MD5End
0.00 0.15 0.00 4 0.00 0.00 MD5Final
0.00 0.15 0.00 4 0.00 0.00 MD5Init
0.00 0.15 0.00 4 0.00 0.00 MD5Pad
0.00 0.15 0.00 4 0.00 0.00 closeconn
0.00 0.15 0.00 4 0.00 0.54 create_hash
0.00 0.15 0.00 4 0.00 0.00 getconn
0.00 0.15 0.00 4 0.00 1556.88 lj_send_request
0.00 0.15 0.00 4 0.00 0.54 md5_hex
0.00 0.15 0.00 4 0.00 0.00 reset
0.00 0.15 0.00 3 0.00 0.54 lj_realloc
0.00 0.15 0.00 3 0.00 1.07 lj_urlencode
0.00 0.15 0.00 2 0.00 36006.75 lj_getchallenge
0.00 0.15 0.00 2 0.00 36009.43 lj_setauth
0.00 0.15 0.00 1 0.00 0.00 create_getfriends_request
0.00 0.15 0.00 1 0.00 1.07 create_login_request
0.00 0.15 0.00 1 0.00 0.77 lj_ask_username
0.00 0.15 0.00 1 0.00 0.54 lj_config_file
0.00 0.15 0.00 1 0.00 76284.83 lj_getfriends
0.00 0.15 0.00 1 0.00 4.83 lj_init_config
0.00 0.15 0.00 1 0.00 73708.73 lj_login
0.00 0.15 0.00 1 0.00 150000.00 main

In looking over the results, it's obvious the problem spots are in delete_hash(), lj_getchallenge(), lj_setauth(), lj_getfriends() (the option I used to test the program with) or lj_login. A quick glance at delete_hash() didn't show any problems, and commenting it out didn't solve anything.

So do the next best thing—run the program under a debugger and follow the execution to see where it might be hanging. A breakpoint in lj_login() (another possible hot spot) and following the code there lead to the following bit of code (from lj_send_request()):

/*
 * First we ditch the headers...if we ever wanted to do
 * anything with the headers this is where we 'd put the code
 * I'm using key here because it' s just as good as any other buffer
 * I could set up a buffer just for this, but let's not waste memory
 */
while (fgets(key, LJ_BUFFER_MAX, conn) && strcmp(key, "\r\n"))
{
#ifdef DEBUG3
  int i = strlen(key);

  if (!strcmp(key + (i - 2), "\r\n"))
    key[i - 2] = '\0';
  lj_debug(3, "[%s]\n", key);
#endif
}

/*
 * Now we read in the key-value pairs.  We're making the
 * assumption that neither the key nor the value will exceed
 * 1024 bytes.  REVISIT THIS
 */
while (fgets(key, LJ_BUFFER_MAX, conn)
       && fgets(value, LJ_BUFFER_MAX, conn))
{
  chomp(key);
  chomp(value);
  lj_debug(3, "Putting [%s]->[%s]...", key, value);
  put(lj_hash, key, value);
}

closeconn(conn);

The code was blocking in the second loop to a call to fgets(). And I pretty much knew what was happening: leaky abstractions (and it's fitting that the article talks about TCP, which is exactly where the leaky abstraction is happening in this very piece of code).

fgets() is a nice function, since it reads in a line of text; if there's no more text to read, it returns NULL indicating there is no more input. But fgets() is (in the case of Unix) written on top of lower level code, notably read(). When applied to a disk file, if there is no more data to be read, read() returns a 0, meaning “no more data.”

But we're not reading from a file. We're reading from a network connection. And therein lies a difference. The function read() also works for network connections, but it behaves just a bit differently in that case. In the case of a disk file, it's pretty apparent when there is no more data to read. But in the case of a TCP connection, it's not clear-cut when the other side has stopped sending data. So read() will just sit there, waiting for data to come in. If there's no data after a period of time (about 30 seconds on my computer) read() will finally conclude that there's no data to be had. That result then bubbles up to fgets() and the loop finally terminates.

But not until a long 30 seconds per request goes by.

No wonder clive is slow (and no, it has nothing to do with “keepalives” in the HTTP protocol—I tested that hypothesis).

The fix is to parse the headers for a “Content-Length” header and read only those number of bytes, but since Wlofie is now using another program, and I don't really post to my LiveJournal (except once a year) there's no incentive to really fix the program (but I did find the problem, which is what I set out to do).

Friday, April 14, 2006

Styling feeds

Yesterday's entry on profiling brings up a topic I've been thinking of recently. You see, when I post code samples, they're coded up as:

<blockquote class="code">
<pre>
#include <stdio.h>
#include <stdlib.h>

int main(int argc,char *argv[])
{
  printf("Hello world\n");
  return(EXIT_SUCCESS);
}
</pre>
</blockquote>

Notice that bit with class="code" there? I use CSS to format the pages here (which allow me flexibility in how things look), and for <BLOCKQUOTE>s marked as such, they get the following bit of CSS associated with them:

BLOCKQUOTE.code
{
  overflow:             auto;
  margin-bottom:        1.5em;
}

Which in browsers that support CSS, mean that those <BLOCKQUOTE>s, if the content exceeds the calculated width of said <BLOCKQUOTE>, then scroll bars will appear just for said <BLOCKQUOTE> (and not as a page as a whole), thus preserving the layout (and yes, I could do away with the <PRE> tags, there's a reason why I don't—keep reading).

And that's fine if you read my blog at my site.

But if you read it through an aggregator (like, say, at LiveJournal) then all the careful styling I came up with is lost, lost, lost. And there's a good chance that if I post code with some really long lines it'll seriously mess up the layout you use to read my RSS feed (and because the CSS doesn't follow the RSS feed, that's why I still use <PRE> tags when I quote code least the code look really strange).

Now, short of including CSS within the tags themselves (using the STYLE attribute, and I really don't want to do that) I don't know of any way to otherwise influence the layout of my RSS feed. It's not that I'm trying to preserve my “look” in RSS aggregators, but it would be nice if I could give “hints” at least. I mean,

THIS

doesn't quite have the same impact as

THIS

See? (and yes, I do have a style for the former defined—“hotflamingdeath” if you must know)

Saturday, April 15, 2006

The Ides of April

Ouch.

I hurt.

I paid my taxes today.

And as a mild protest, I wrote the following on my check:

In this world nothing can be said to be certain, except death and taxes.

Hope I don't get audited.

Sunday, April 16, 2006

The other 364 days of the year

Ever wonder what the Easter Bunny does the other 364 days of the year?

Now you know (link via Tryss).

Monday, April 17, 2006

I guess it's the train wreck syndrome at work

I came across something I wanted to link to today, but I had to get caught up first.

By the time I got caught up, I forgot what I wanted to link to.

But then I found it again:

I didn't really understand the parody in Lost in Translation until I saw the real Tara. At one point she's riding through Europe on a Gondola, explaining Sex in the City references as if she were some kind of tour guide.

I found myself unconsciously picking out sniper positions in the surrounding buildings. This … this is why people hate America.

Tara Reid ate my soul

I guess since the United States does not have an aristrocratic class to make fun of, we have to make do with what we got (and frankly, it's pretty pathetic).

Tuesday, April 18, 2006

Sugar, spice and power tools

It's always nice when I have dinner with a friend. And normally, this isn't something I would necessarily blog about, but said friend sprung a surprise on me—she (and yes, it is a she) has a wood working shop in her garage! It's rare enough to find anyone with a decent wood working shop in their garage, and it's even rarer to find a woman with a wood working shop.

There is nothing cooler than a woman with power tools.

A wood working shop!

How cool is that?

I'm still amazed.

Wednesday, April 19, 2006

Found another deck

It's not a popular or a common game, so it's always neat when I come across some other group that's playing 1000 Blank White Cards (link via Shadesong).


Eulogy for a dead python

If you are going to have singing done at your funeral, why not have it be Eric Idle singing “Always Look On The Bright Side of Life”? Oh, and I suppose it wouldn't hurt to have John Cleese calling you a free loading bastard either.

Thursday, April 20, 2006

A Dead Ringer

For the past few months, Smirk has been working to set up a VoIP system for work so all of us at the Office could opt to work from home if we so choose—all office calls would be forwarded appropriately to our various homes. I personally would rather work mostly from home as it's more comfortable, and I save a 38 mile round trip.

So Smirk is doing his part to be enviromentally sound.

I say all of this because the phone system here at the Office is wonky. Our main 800 line is non-functioning and Smirk is still trying to figure out what's going on with The Monopolistic Phone Company about that. And the phone on my desk has been acting weird—or it could be the answering machine it's plugged into. The phone doesn't ring and the only indication that there's a call is the answering machine suddenly kicking on.

As this was happening, I just figured it had something to do with Smirk working on the VoIP for the office (I run the network—I don't run the phone system) or The Monopolistic Phone Company having fun at our expense (not the first time). Or the answering machine is going.

I just now got a call from Smirk and I informed him of the odd behavior with the phone on my desk.

“Did you check that the ringer is on?” he asked.

“The what?”

“The ringer. On the phone. Is it turned on?”

“The ringer?”

“The ringer.”

I checked.

It was turned off.

D'oh!


Speaking of phone systems

Later on in the day, Smirk dropped off the new VoIP unit I'll be using at home. It's a Linksys PAP2 and the installation couldn't be easier—it was literally plugging the power cable in, the Ethernet cable in and the phone cable into phone plug #1 (I initially plugged it into phone plug #2 and when I went to make a call, I heard a computerized voice telling me I had plugged the phone into the wrong port). I was then ready to go.

Of course, Smirk had already signed up the unit for Vonage so I'm not sure of all the details about that, but I was impressed with the hardward after it was delivered to my hands.

The few calls I tried were fine quality wise. Smirk has been using the same unit for a few days now and I hadn't even noticed. All in all, it seems like a decent unit.

Update on Friday, April 21st, 2006

About the only complaint I have so far about the unit is the unnaturally bright LEDs on the front of the unit. They were so bright I had thought I left my curtains open and the street lamps where shining through when I turned out the lights to go to bed. I turned the unit off so I could sleep.

I'm going to have to find some way of cutting the light down a bit.

Friday, April 21, 2006

“So how is this any different than a cell phone?”

At the weekly D&D game this week, I mentioned to everyone there the new VoIP phone I received for work, and how the unit can be plugged into any network and still receive calls for the phone number assigned to it.

“So why not use a cell phone?” asked Marco, ever the smart one in the group.

“Um …” I said. “I don't know.”

Um … I suppose it might have something to do with forwarding tech support calls, but honestly, I don't know.

Saturday, April 22, 2006

Make Zillions on the Intarweb

A few weeks ago durring my daily web surfing habits, I came across one of those “Make Zillions on the Intarweb” type pages. I read through the typical sales pitch when I saw that I could order a free book on how to make zillions.

The fine print? Shipping and handling charges that totalled maybe five bucks. I figured that at the price of lunch, it might be worth it to see what the typical “Make Zillions on the Intarweb” book might be like and blog about it. So okay, I ordered it.

Consider it five bucks for bloging material.

The package arrived today.

It came with some fliers, a book and eight (!) audio CDs on “Aggressive WealthSM” with typical scenarios like real estate, Internet income and stocks. On the back of one of the fliers is:

Accepting our offer was a great decision!! [sic] Now make another one … listen to the FREE Making Money audio CD “Selling Yourself Wealthy” and begin reading your free copy of “I Got Here, You Can Too!”SM That's right, those two products are yours FREE, no matter what you decide. You received these two products FREE for considering the Aggressive WealthSM program, the proven money making audio collection that is at your fingertips.

YOU WILL BE BILLED A ONE TIME CHARGE OF ONLY $99.90 AT THE END OF YOUR 30 DAY CONSIDERATION PERIOD ONLY IF YOU DECIDE TO KEEP THE ENTIRE BRUCE A. BERMAN AGGRESSIVE WEALTHSM PROGRAM.

Okay, I get 30 days to decide to keep the entire package and if I don't want it, I can send it back. But wait? What's this? Printed else where on the flier is this bit:

During your 30 day consideration period, please take the time to read your free book, “I Got Here, You Can Too!” and also listen to your free Making Money Audio CD, “Selling Yourself Wealthy.” These two products will give you a free, no obligation demonstration of our program. If you do not wish to keep the entire Aggressive WealthSM program at the discounted price, simply call our toll free customer care line at 1-877-XXX-XXXX for your return authorization number and return instructions. Return the Aggressive WealthSM Audio Collection, which is in your hands, and you will never be charged for them. However, after 30 days from our shipping date, you will be charged one payment of only $99.90 for the entire audio collection.

(emphasis added)

Nice—30 days from when they shipped it, not from when I received it. So it's probably more like 25 days or so. And it's probably best I not break the seal on any of the CDs least I can't return them. And I probably pay shipping costs back.

Nice racket.

I'll be making posts from time to time as I go through the materials. Stay tuned …

Update on April 28th, 2006

The price of admission drops $85 … I think I'll stick around.

Sunday, April 23, 2006

The Mysterious Key Ring Separation at IHOP

Gregory invited all at Casa New Jersey out to dinner, so we hopped on over to the local IHOP. After eating we were hanging out in the parking lot talking. As we were talking I was spinning my keychain on my finger (a nervous habit).

About ten minutes go by when The Younger finds something a few feet away from me. “What's this?” he asks, holding up a small key ring with some keys and a grey frob.

I took a look at it when I realized it was part of my keychain! (the grey frob is the key to the server room) It had somehow flew off! How I do not know, given that these are key rings, the type that you have to really force apart to get keys on.

Very strange indeed.

Monday, April 24, 2006

A reasonable judgement

NEW YORK (AP)—Surfing the Web at work is equivalent to reading a newspaper or talking on the phone, an administrative law judge said in recommending the lightest possible punishment for a city worker accused of disregarding warnings to stay off the Internet.

Judge: Employee Web surfing not unreasonable

Wow!

An actual, reasonable decision from a judge dealing with computers.

Who'd a thunk it?

Tuesday, April 25, 2006

Ch-ch-ch-changes

Ring.

Ring.

“Hello, Technical Support,” I said.

“Hey, this is F from XXXXXXXX.” It's the cusomter we set up the IP tunnel with DSL backup a few months ago. “Our T-1 was just installed.”

“Okay,” I said, unsure of the implications of what F just said. What does that have to do with us? I'm thinking.

“I was wondering if the T-1 has been installed on your end yet?” asked F.

Excuse me? I thought.

“The T-1 on your end. We're getting a T-1 through you guys,” said F.

“Oh, was that my ‘out loud” voice?”

“Yes,” said F.

“Ah.”

So.

That was how I found out about the new T-1 installation for our customer about a week or so ago. They dropped the IP tunnel and decided on a dedicated circuit with us. And they're keeping the DSL backup connection.

Now, the DSL circuit on our end comes in one Cisco router. The dedicated T-1s on our end come into another Cisco router. In this case, the T-1 is the primary circuit and the DSL is the secondary circuit.

Well, either we go static routing and I'm on call 24/7 and can never be more than two minutes from an internet connection so I was rewroute things if the T-1 fails, or we use a dynamic routing protocol like OSPF to handle these things for us.

I'm having to learn to configure OSPF across four routers to get this accomplished.

OSPF is not entirely new to me, but we only have it running between two routers, one on our side, and one to another customer. This customer though, requires OSPF configurations across four routers.

Fortunately, it wasn't that hard to set up, but it's not complete yet.

[Portion of our  network running OSPF]

That firewall between our core router CORE and our DSL router DSL is keeping OSPF from communicating across all the routers—OSPF communicates directly with neighboring routers, and that firewall isn't a neighboring router.

To fix that, I need to:

  1. Set up a virtual OSPF link between CORE and DSL, but that apparently involves multiple OSPF areas, which is something I don't care to get into with a network this small (and frankly, we can get by entirely with static routing if it weren't for the redundant links).
  2. Set up OSPF on the firewall. Easier than the first option, but still requires some work.
  3. Remove the firewall entirely. Nearly all the customers on DSL already have a firewall locally (heck, nearly everything that hooks up to the Internet has a firewall) so removing the firewall isn't that much of an issue.

Of those, the third option is the easiest one to handle.

Once the firewall is out of the way, and the T-1 functions between us and XXXXXXXX, then OSPF will handle the changes in routing in case any of links to our customers go down.


A reason for VoIP

About the Vonage phone I recieved a few days ago:

From
Jeff Cuscutis <XXXXXXXXXXXXXXXXXX>
To
Sean Conner <sean@conman.org>
Subject
Voip phone
Date
Tue, 25 Apr 2006 16:17:28 -0400

Those are very useful. After the hurricanes last year, we relocated the company to a hotel in Orlando with wifi and just forwarded the office number to the vonage number. It was pretty cool.

Jeff

Okay, there is that.


Styling feeds II

The previous entry brings me back to the styling feeds topic I brought up a week or so ago.

Normally, I tend to quote email headers in posts as:

<p>
<b>From:</b> John Doe &lt;<span class="cut">XXXXXXXXXXXXXXXXXXX</span>&gt;<br>
<b>To:</b> Sean Conner &lt;sean@conman.org&gt;<br>
<b>Subject:</b> You know, your posts are boring<br>
<b>Date:</b> Date: Tue, 25 Apr 2006 17:17:17 -0400
</p>

<p>You know, your posts are getting awfully dull lately ... </p>

Which would be rendered as thus:

From: John Doe <XXXXXXXXXXXXXXXXXXX>
To: Sean Conner <sean@conman.org>
Subject: You know, your posts are boring
Date: Tue, 25 Apr 2006 17:17:17 -0400

You know, your posts are getting awfully dull lately …

But there was an entry last month that made me rethink how I wanted to construct the headers when quoting email—basically, long email headers can span multiple lines but each subsequent line of a header should be indented with white space, and with the formatting I have above, that distinction isn't preserved (as well as the headers inherit the full justification I have for all my paragraphs, which shouldn't happen either).

So I thought about it, and I decided that really, headers could be construed as a type of dictionary list—a list of terms (the header name) and their definitions (the header contents). So the above would be encoded in HTML as:

<dl>
<dt>From</dt>
<dd>John Doe &lt;<span class="cut">XXXXXXXXXXXXXXXXXXX</span>&gt;</dd>

<dt>To</dt>
<dd>Sean Conner &lt;sean@conman.org&gt;</dd>

<dt>Subject</dt>
<dd>You know, your posts are boring</dd>

<dt>Date</dt>
<dd>Tue, 25 Apr 2006 17:17:17 -0400</dd>
</dl>

Which I would like to render as:

From
John Doe <XXXXXXXXXXXXXXXXXXX>
To
Sean Conner <sean@conman.org>
Subject
You know, your posts are boring
Date
Tue, 25 Apr 2006 17:17:17 -0400

Only if you aren't viewing this on my site with a CSS-capable browser, you won't see the intent I have for formatting, which gets us back to the post I made last month.

Am I the only one that has this concern over how my entries are presented?

Anyway, if the quoted email in the previous entry looks a bit odd, that's why—you aren't seeing it how I intended it to be seen.


A night of bogarts

While the T-1 may have been installed at XXXXXXXX, the router there (that we supplied) doesn't have a T-1 interface. So after work I drove over there to install one.

I had been in the process of setting up OSPF and installing some firewall rules (they are one of the few DSL customer that didn't have a firewall) when I lost the connection for a minute or so. It came back up before I left, but as I was driving over there, I received a call from F at XXXXXXXX saying the connection was down. I said I was on the way over and I'll take a look when I get there, so I didn't think too much on either incident.

Once there, I powered down the router, installed the interface and powered the router back up. A minute or two to let it boot up, and yes, they are down. I couldn't even ping the router, much less surf the Intarweb. I could see that the router was up and running, but without the special console cable, I couldn't diagnose the problem.

I then drove back to The Office. I couldn't reach their router from our side, so I grabbed the special console cable and headed back to their office.

Once back there with the ability to log into the router, I could see the problem—plugging the T-1 card in renumbered some other interfaces, including their DSL interface. When it powered back up, the configuration for interface ATM0/0 (the DSL interface) was ignored because interface ATM0/0 didn't exist. And consequently, interface ATM1/0 wasn't configured because there was no configuration data for interface ATM1/0.

And silly me, I didn't have a copy of the router configuration on hand, so it looked for a minute like I would have to drive back to The Office, print out the configuration for this router (I have backups of all our routers on my workstation) then drive back to the XXXXXXXX office, but then I had a better idea: I called Wlofie, had him log into my workstation and read off the DSL interface configuration.

That done, the connection came right back up. Then I could turn my attention to configuring the T-1 interface.

Only it didn't come up an interface, but a “controller.”

Okay.

Didn't think much of it until I realized I couldn't assign an IP address to the T-1 interface controller. So I did what I always do in such a situation and called G, our Cisco consultant.

Turns out that the interface card we had was a voice T-1 card and not a data T-1 card.

Well.

Not much I can do until I get the right card (and we don't have a data T-1 card for this particular router at the office). But since the DSL was back up and running, I decided to call it a night.

Until half an hour later when I got a call from Smirk—they were still down. Fortunately, I was still in the area and had access to a computer. A quick test showed the DSL was up, but that anything else on their network was unaccessible. I called XXXXXXXX and talked to their IT manager C.

Now C is a nice guy and I'm sure he knows his computer stuff, but networking is not one of his strong points. And it because clear to me that I was going to have to go back and debug their network.

I knew the router was okay, since I could get to it from the Internet. And when I got to their office, I checked out their Linksys wireless unit (which does NATting) and found nothing wrong with it. That left the only thing sitting between the two—a switch.

On a lark, I power cycled the switch.

Their network started right back up.

It seems they've been having some power “issues” recently.

Sigh.

Everything else had been powercycled.

But the switch.

Of course.

Wednesday, April 26, 2006

That sick feeling in your stomach when you know you created a huge mess

I thought I would go ahead and remove the firewall between our core router and the DSL router. I made as much preparation as I could before 5:00 pm, the end of the business day.

At about 5:05 pm I swapped some network cables around.

And the Internet broke.

I'm not sure why it didn't work. At first, I thought maybe it was the VLAN I created on the core router for the DSL router port (to segregate the network traffic and cut down on broadcasts) and reverted that.

The DSL circuit was still down, and my phone started ringing.

I then thought that I needed a crossover cable, but I was getting a link light when using the existing cable.

And the DSL circuit was still down.

The routing changes I had to make looked good, but still, no DSL.

Clearing the ARP tables didn't help [but I just now realized, in writing this, that I only cleared the ARP table on the core router, and not on the DSL router—hmmmm].

So I had to revert everything back while trying to keep myself from getting sick.

Blah.

Thursday, April 27, 2006

More reasons to use VoIP

Smirk finally read the entry about cell phones vs. VoIP and gave me five reasons for using it over a cell phone:

  1. It saves me from wasting my minutes on my cell phone—or rather, it saves my other boss cell phone minutes since he pays for the cell phone.
  2. We get unlimited local calling and the international rates are cheap (which is important to us since we have a few international customers).
  3. Once we transfer the tech support lines to the new number, it will always follow us no matter which network we plug the VoIP unit into.
  4. Because it's cool!
  5. Because Smirk wants to keep me awake at night with the bright lights on the unit.

So, now I know.

Friday, April 28, 2006

“We REALLY want your money”

Last Saturday I received my information package on “Aggressive Wealth” by Bruce A. Berman with 30 days (since they shipped) to hold onto the material before being charged $99.90 for eight audio CDs. Today I got around to calling the toll-free number to start the return and not get charged.

Amazingly I was talking with a human operator in less than 30 seconds, but I couldn't quite place the accent (Jamaican perhaps?), but the operator spoke clearly enough that I could understand even over a cell phone. I had to verify my name, zip code and email address before we could continue with the return process. Right then, the price dropped to $74.90.

“No, I want to return the CDs,” I said.

So then came the instructions—write the return code on the return package, please use a padded envelope and insure the CDs for $100 value. Am I sure I want to continue. Yup, and I got a return code.

And another price drop to $49.90.

“No, I still want to return the CDs,” I said, amused that the price of the eight CDs, retail price of over $300 has dropped yet again.

Okay, please send the package to the given address, which I had to read back to ensure I had it correct, but what about another $25 off? I can keep them for only $24.90.

“No, I'd rather return the CDs,” I said.

I was then asked why I wanted to return them. I said I was only interested in the book and wasn't expecting to get an additional eight CDs (even though the operator said they were listed on the website), and that I'll go through the hassle of returning them.

But what about $14.90? That's it, account closed.

$14.90 … so far I paid about $5.00 (lunch) and another $15 would bring it up to a nice dinner and heck, I am curious. So why not? I'd probably spend about $5 anyway sending the darned things back, and I'm still under the price of the book from Amazon.

Although I have to wonder … had I stayed on the line a bit longer, would the price have dropped even more?


Just because we work with computers does NOT mean we clean Windows!

Someone from a neighboring office just walked in and started going on about his computer system getting a Trojan and how his virus scanning software let it slip though and his IT guy mentioned something about getting some other virus scanning software and could we (“we” being the resident computer experts in our office building because “we” do “stuff” with computers) recommend software they should get.

“Um,” I said. “Don't use Windows?”

I don't think he heard me because he then asked me what I use.

“Not Windows,” I said.

“What?” From the tone, I gathered that such a statement has no validity in his world view and that everyone uses Windows. “What do you use, DOS?”

“I use Linux,” I said, pointing to my workstation. “At home I use Macs. I just don't have virus problems.”

“So can you recommend anything?”

“I'm sorry, but I'm not the person to ask.”

He then said good-bye and walked away, mumbling something that I couldn't hear.

Saturday, April 29, 2006

Time to do networking right

Unlike Wednesday, I have all the time I want to remove the firewall between our core router and the DSL router.

It went much smoother if a bit longer than I expected. The big stumbling block wasn't cached ARP entries like I suspected, or even the wrong type of cable but the phyical port configurations. When one side (the DSL router) had a link light, but not the other side (our core router) it hit me that it might be the port settings. Our core router had the port pegged to 100Mbps, full duplex with no autonegotiation of port settings, and didn't care for the DSL router attempting to autonegotiate the settings. Once I reconfigured the port on the core router to autonegotiate, the link came up, and OSPF worked flawlessly across all five routers running it.

So now all that remains is getting the T-1 install for XXXXXXXX and weighing the routes appropriately.

Sunday, April 30, 2006

Poor defaults in a user interface

I was on my cell phone when it chimed. At the time I thought it was someone trying to call me, but afterwards, there was no indication of a missed call and nothing new on my voice mail.

Wierd.

Then, maybe an hour or so later, it chimed again. By the time I could get to it, there was no indication of what happened to cause my cell phone to chime.

Then another hour or so later, it chimed yet again. This time I was able to get to it to see it flash the “Low Battery You Idiot! Recharge Me!” message for about two seconds before it went away.

While it's nice that the message will go away unattended, it's not nice that it goes away in two seconds. Five seconds, I might have caught it the second time (when I wasn't chatting away on the phone). Ten seconds might be better.


I wish I could do networking right

I may have spoke too soon.

Smirk called and said he was experiencing DSL issues—his connection dropped several times today for up to a minute or so. I told him it might be a port configuration problem (which is what caused the problems on Wednesday) and that I would talk to Dan the Network Engineer about it (Dan being the expert on the type of router we use for our core).

But I took a look, and from what I can see, it may not be a port issue but an OSPF issue:

May 01 00:07:12 XXXXXXXXXXXXXXXXXXXXXXX %OSPF-I-ADJCHGFROMFULL, Process 0, Nbr XXXXXXXXXXXXX on interface XXXXXXXXXXXXX changed from state FULL
May 01 00:07:12 XXXXXXXXXXXXXXXXXXXXXXX %OSPF-I-ADJCHGTOFULL, Process 0, Nbr XXXXXXXXXXXXX on interface XXXXXXXXXXXXX changed to state FULL, Loading Done
May 01 00:09:25 XXXXXXXXXXXXXXXXXXXXXXX %OSPF-I-ADJCHGFROMFULL, Process 0, Nbr XXXXXXXXXXXXX on interface XXXXXXXXXXXXX changed from state FULL
May 01 00:09:36 XXXXXXXXXXXXXXXXXXXXXXX %OSPF-I-ADJCHGTOFULL, Process 0, Nbr XXXXXXXXXXXXX on interface XXXXXXXXXXXXX changed to state FULL, Loading Done

The interface in question is the one between the core router and the DSL router. It doesn't seem to have anything to do with one of the OSPF routers participating is at the end of an authenticated PPPoE connection over DSL since the only complaints seem to be isolated with the connection between the core router and the DSL router.

Looks like I'll be doing some heavy reading in the next day or so.

Obligatory Picture

[The future's so bright, I gotta wear shades]

Obligatory Contact Info

Obligatory Feeds

Obligatory Links

Obligatory Miscellaneous

You have my permission to link freely to any entry here. Go ahead, I won't bite. I promise.

The dates are the permanent links to that day's entries (or entry, if there is only one entry). The titles are the permanent links to that entry only. The format for the links are simple: Start with the base link for this site: https://boston.conman.org/, then add the date you are interested in, say 2000/08/01, so that would make the final URL:

https://boston.conman.org/2000/08/01

You can also specify the entire month by leaving off the day portion. You can even select an arbitrary portion of time.

You may also note subtle shading of the links and that's intentional: the “closer” the link is (relative to the page) the “brighter” it appears. It's an experiment in using color shading to denote the distance a link is from here. If you don't notice it, don't worry; it's not all that important.

It is assumed that every brand name, slogan, corporate name, symbol, design element, et cetera mentioned in these pages is a protected and/or trademarked entity, the sole property of its owner(s), and acknowledgement of this status is implied.

Copyright © 1999-2024 by Sean Conner. All Rights Reserved.