revjim.net

August, 2003:

Courier is stupid

It can login. It can create messages. It can create folders. It does all of this as the user that owns the account. That’s perfect. But, if the INBOX doesn’t exist (even though all the folders leading up to it do) it can’t. That’s silly. So now, when I create a new user account, instead of just creating /var/sites/domain.com/mail/username/ I have to create it plus /var/sites/domain.com/mail/username/new/ and /var/sites/domain.com/mail/username/cur/.

Whatever.

Also, they claim that, good IMAP clients will support the NAMESPACE features and automatically recognize where mail goes and where new folders should be created. Well… that’s just peachy. But, why not just do it automatically and then even bad IMAP clients will work. How hard would it be to add a feature that says “if a folder is being referenced, for creation or access, or message copy, that doesn’t start with “INBOX.”, add it for them. Additionally, if a ‘/’ is specified in the folder name, convert it to a ‘.’”? Then, all of the problems would be solved and ALL IMAP clients would work pretty well.

To make matters worse, Outlook Express seems not to recognize Courier’s NAMESPACE features, so you have to make that setting by hand. And, Evolution, regardless of whether that setting is made or not, insists on showing mail folders under INBOX. Ugh.

creationists, evolutionists: lend me your ears

There is no point in debating the creationist and evolutionist points of view on “creation” until evolutionists recognize ONE thing:

Let’s say, for a moment, that the evolutionists ARE right. Let’s say that, 18 bazillion years ago, the entire universe was a speck of dust that exploded in a massive ball of fire and fury, that expanded to create the universe as we know it today. And in that expansion, the Earth was created, and one fine summer day in the land of inorganic material an organic single-celled creature emerged which resulted in the eventual evolution of every living creature known today. Assuming ALL of this is correct: how did the speck get there? Someone, something, some process created that speck. Something can not be created out of nothing. Or, if it can, give us an explanation. And, until you have one, you need to at least acknowledge whatever created that speck as a “higer power”. And, regardless of what Science you use to prove otherwise, there will never be a method of showing how nothing created something. Even if you can determine how that speck of dust got there in the first place, the creation of whatever created that speck of dust will be indeterminate.

If the creationists want to say that “one day is with the Lord as a thousand years, and a thousand years as one day” (2 Peter 3:8) and that the “six days [in which] the LORD made heaven and earth, the sea, and all that in them is” (Exodus 20:11) was, scientifically, longer than six days, that’s fine… you can debate that with them all you want. However, don’t try to say that the creation of the universe occured without a “higher power”. You have no way of proving that, and you never will. It just isn’t possible. Eventually, you will be led to something that just… was or is… with no explanation.

And creationists: please stop trying to convince the evolutionists that a “higher power” exists. If they deny that concept, then they are fooling themselves and debate with them is futile, at best.

EXIM: done

Wow! After a lot of work, Exim is finally configured exactly how I want it to handle multiple domains. Well, not exactly. I haven’t implemented the MySQL portions yet. However, I’ve written them, and I’m pretty sure they work. I decided that I wanted mail to be able to function with or without MySQL, with a preference to the MySQL information. This way, if you’re like me and like editing configuration files by hand, you can. Here’s how it works.

Every domain that can receive mail must have a directory in /var/sites/ named the same thing as the mail domain. This is because, due to the virtual nature of all of the mail functions, each domain needs it’s own spool directory. Inside of /var/sites/domain.com/ there must exist a directory called mail as this is where the mail spool goes. /var/sites/users holds domain to system user information. This allows exim to be the right user when it delivers mail for each user. This makes the system more secure… I think. It also provides a user to become when performing pipe operations and the like. Each user account that exists for a domain must have a directory with the name of that user in /var/sites/domain.com/mail/. This is because I choose to use MailDir for message delivery and it needs a directory to store mail in. In actuality, the users Inbox will be at /var/sites/domain.com/mail/username/INBOX/, allowing IMAP users to store other folders in the same location. If a /var/sites/domain.com/aliases file exists, it can be used to look up forwards, pipes, and mailing lists. If /var/sites/domain.com/mail/username/filters exists, exim will process it like a .forward file, or an Exim filter file. If /var/sites/domain.com/mail/username/.procmailrc exists, procmail will process the mail (I’m not sure if this part works or not… it’s untested). If mail is addressed with a prefix of real- to ANY address, it bypasses any filters or procmail files. This allows the mail system to inform the user of an error in those files without those messages being processed by the offending files.

When I uncomment the MySQL lines, it should allow me to have a MySQL database with two tables. One will be called “domains” with two fields: owner and domain. It will serve the purpose of the /var/sites/users file. Another table called “aliases” will have three fields: user, domain, and alias. It will serve the purpose of the /var/sites/domain.com/aliases file.

This setup shold provide the ultimate in security, flexibility, and features. Take a look at my exim.conf file if you’re interested in how it was done.

Even though it was a lot of work (as I didn’t really know much about Exim before today), I really like Exim. Once you get used to it, it just makes sense. Their ${lookup style notation is a little… hard to read, but you get used to it after a while.

Next step… set up courier to read these directories. Isn’t this fun?

stupid people: satellite images of blackout

Out of all of the satellite images of the blackout available and circulating amongst news sources and weblogs, the people in my office decide to circulate this one via email:

Obviously, this is a fake. First of all, how is it possible that the “ISAT Geostar 45″ managed to take a picture of the entire US and Canada at precisely 23:15EST on Aug 14th without a cloud in the sky or any obstruction anywhere? Secondly, how is it that the blacked-out portions of the US are darker than the ocean which is as dark, if not darker, than those areas affected by the blackout?

What makes it even worse is that the people that are circulating this don’t even realize it’s a fraud. I got it as a forward which was a forward of a forward which was forwarded to someone who received it as a forward from someone else. And each of these people, as always, left their comments along the way. Things like “If you haven’t seen this picture yet, it’s awesome” and so on.

Think people! Jesus. Just consider, for once, that not everything someone tells you, and certainly not everything you get on the Internet, is 100% true.

Slow but steady

So far, the DNS module of the control panel daemon can add a SOA record, add an RR record, delete an SOA record, delete an RR record, and list RR records. Additionally, it’s all done in a user authenticated way making sure that the user requesting such things is authorized to do so. It pretty slick, and I’m pretty proud of it. Justin built all the initial framework (the SQL queries and such) and I added business logic, error checking and authentication. That’s all that is needed for the DNS module, I think.

I may end up adding one function that creates a DNS records for people who aren’t allowed to manage their own DNS or for those who would rather have it automatically setup and then fine tune it later. It’ll add the domain and make it owned by them, but, they’ll be unable to manage it because they won’t have manage permission. Instead, it’ll allow access if you have permission to create web or email domains. It’ll read a config file to get default hostnames that need to be established and build the entire thing in one shot.

The next step is the Apache module. Hopefully… now that there is a nice framework going, this next module will go quicker.

After that email. Then MySQL. Then write the GUI. Gimme… 3 months… tops. :)

PHP: classes, functions and error handling

PHP has set_error_handler(), trigger_error() and friends. But they aren’t exactly up to par for handling massively abstracted code. So… how do you handle errors? Here’s an example. It’s overly complicated for something so simple, but… that’s because it’s merely a simple example.

Imagine you have a block of PHP code like this:

$res = add_two_numbers(15,27);
print $res;

Now let’s look at the add_two_numbers() function:

function add_two_numbers($a,$b) {

$calc = start_super_number_calculator();

add_number_to_stack($calc, $a);
add_number_to_stack($calc, $b);
perform_operation_on_stack($calc, 'add');
$result = get_number_from_stack($calc);

return $result;

}

I won’t bore you with the code for the “super_number_calculator”. However, let’s look at the above function. What happens if, for what ever reason, start_super_number_calculator() has an error. In the above case we could test to see if $calc was a valid calculator resource identifier, and, if it wasn’t, we could return an error. But how would we return that error? We could return false;. But, what if we want to know WHY there was an error? We could use trigger_error() and an error handler to trap the error and obtain additional information. But, since you can only define one error handler at a time, you’ll have no way of knowing whether that error message should be displayed to the user or not. Since, unless you want to code in the line numbers and file names of the various pieces of your application, you won’t know exactly where the error came from… you’ll have no choice but to either display all errors (of a certain type) to the user, or to not display them. That’s less than ideal.

So, let’s say we don’t want to know why there is an error — we just want to know that there was one. Then set_error_handler() might come in handy. However, what if, in some cases, an error is… okay… ignorable… whatever? Then set_error_handler() doesn’t work. Okay… so then, back to idea number 1: well just return false; and test for that. That’s great… except… what if I made a new function called is_this_a_number()? This funtion will return true or false depending on if it is a number or not. How do I know if that false that is returned means it is NOT a number… or there was an error in processing?

The only solution I can think of, and it isn’t a good one, is to have all functions return an array. The first element of the array is ALWAYS either true or false. If it is true, the expected return values will be the next elements of the array. If it is false the next 2 elements will be an error number, and an error message. Unfortunately, this makes code look pretty messy.

Another option, that I don’t usually employ, is to write a universal function called hey_php_you_stupid_fuck_is_this_an_error_or_not(). If there is an error in processing, a function should return a struct that contains an element named “_##_ERROR_##_”. The error checking function looks for that element in the return value, and returns true if it is seen. Then, the code knows that the error message and error number are available in the struct. This means that, after every function call, instead of checking if the first element is true you run it through hey_php_you_stupid_fuck_is_this_an_error_or_not(). It accomplishes basically the same thing. However, it does so in a way that allows “legacy” functions to operate normally (without proper error reporting) without altering any code. Actually, now that I think about it, this option might actually be better than the one I currently use. But… it still isn’t that great.

So… I ask again: how do you do it?

best. SPAM. ever.

I’ve just received one of the most amusing pieces of SPAM ever.

If you and your spouse can’t wait to be apart, then this is for you!
At FREE DIVORCE we understand how expensive it can be to get a divorce,
but with our do-it-yourself divorce kit, we have taken away the time,
hassle and expense. It’s fast and easy! You can get rid of your
insignificant other in no time at all.

phish out of water

Mike Gordon, basist for Phish, was caught in a secluded area after a Dead show with a 9-year old girl. He wasn’t caught doing anything “bad”, per se, but he there’s really no reason for him to be in a private area at 1am with a 9-year old girl that isn’t a friend or a family member. Apparently, she is the daughter of a Hell’s Angels leader. Both the girl’s father and Phish have told the media to stay out of their business and allow them to deal with it privately. Gordon admits that he may have used bad judgement, but insists that he is not a pedophile and was merely taking “art photos”. [Thanks Jaclyn]

lobster

My dad just called to invite me to have all-you-can-eat lobster with him and my mom this evening at 6:45pm. It’s at a place called Le Port (which, in American, is pronounced “lee port”). Should be fun.

Atom API Implementation

Mark has posted an Atom API Implementation. There’s a lot of writing there. But if you read through it, you’ll realize that it really is very simple. It just makes sense. And when things makes sense, that means they are usually easier to understand and easier to implement.