March 10, 2003

BZZT! You LOSE!


Warning: DOMDocument::loadHTML() [function.DOMDocument-loadHTML]: htmlParseStartTag: invalid element name in Entity, line: 57 in /srv/www/darkness.codefu.org/root/wordpress/wp-content/plugins/postxform/postxform.php on line 43

Warning: DOMDocument::loadHTML() [function.DOMDocument-loadHTML]: Unexpected end tag : p in Entity, line: 78 in /srv/www/darkness.codefu.org/root/wordpress/wp-content/plugins/postxform/postxform.php on line 43

Warning: DOMDocument::loadHTML() [function.DOMDocument-loadHTML]: Unexpected end tag : p in Entity, line: 84 in /srv/www/darkness.codefu.org/root/wordpress/wp-content/plugins/postxform/postxform.php on line 43

So SquirrelMail isn’t real editable. SqWebMail has nice HTML template files with simple placeholders for values. (OK, that’s an overstatement. There is some weird shit that goes on in SqWebMail templates. Still, they can be loaded in to FrontPage.) (Let me go on to emphasize that I do not use FrontPage but many foolish people do.) Editability may quickly become very important. OTOH, it might not, and SquirrelMail was way easy. I’ve decided to complicate my life instead and install IMP.

First thing I noticed about IMP? It requires the Horde Application Framework. Fuck me.

So I grab the Horde Framework. Install instructions start out by telling me that, without a database, my “user preferences” will not be maintained between sessions. Yay! A database, just what I wanted to install. apt-get install mysql-server php-mysql. Also requires IMAP support in PHP; apt-get install php-imap.

Horde actually has a lot of requirements. There’s Gettext and XML support, which I hope were built in by Red Hat. There’s Mcrypt support, which is supposedly maybe optional. Then there’s PEAR modules. PEAR, as near as I can tell, is PHP’s answer to CPAN. Apparently it has a cute command line utility called, unsurprisingly, pear. The instructions tell me I need the Log, Mail_Mime, and Net_Socket (optional) modules. I can install any of these modules like pear install <module name>. Riiight, so pear install Log yields:

'DB' PEAR package is not installed

OK, no problem. pear install DB goes swimmingly as near as I can tell. So we try pear install Log again and get:

Relation 'has' with requirement '' is not supported
Dependencies failed

Kick ASS. That is a fucking awesome error message. Thankfully I found someone that says to disable dependency checking. OK, great, pear install -n Log and we feel successful. Net_Socket installs easily. There is some chattering about how this method requires a static PHP or something, blah blah blah. RH8 users can ignore this I think; I believe it’s talking about how the php binary isn’t normally built with a dynamic Apache module or something.

service mysqld start, mysqladmin -u root password my-new-password for MySQL. I hope that’s enough to make it happy, and me too. Untar the Horde tarball into our (new) root directory. (See previous SquirrelMail tree for the root directory; I moved my SquirrelMail root over to a backup directory for now.) I mv horde-VERSION horde, then cd horde/scripts/db and run mysql -u root -p . Surprisingly, ran without error and mysql -u horde -p horde (password horde) works afterward too. Will wonders never cease.

Pop in to horde/config and run for file in *.dist; do cp $file `basename $file .dist`; done as per the instructions. Edited config.php and skipped down to the “Preference System Settings” section. Set it for SQL use, uncommented the MySQL example and filled in the password. I ignored most of the helper application paths that I supposedly needed to change in mime_drivers.php; most of them looked correct or like something I didn’t care about. (Right now, at least. I’m more interested in seeing how this thing functions.)

Now we’re ready for Horde action. Hitting http://my.server/horde/test.php yields a few things:

  • Doesn’t see IMAP or MySQL support, or Mail_Mime PEAR package. service httpd restart fixes this.

  • It says my version of PEAR isn’t recent enough. Bollocks to that.

Everything else is OK. So Horde: installed. Now IMP. IMP had better be fucking good.

Read IMP docs. Looks like I have all the dependencies. Edit the Horde registry.php with both of the changes mentioned (status change to active and uncommenting the authentication lines). Do the same for loop as above except this time in the imp/config directory. Now editing config.php. I enable Aspell because I’m bored. Skipped the rest of the file, as it was more boring. In servers.php I delete every server entry except for _prompt and cyrus. I modified cyrus to fit my Courier setup, which basically mean changing the key (from $servers['cyrus'] to $servers['courier']), name, server, maildomain, and realm.

Time to test. Going to http://my.server/imp/ yields an error in imp/lib/base.php. Apparently IMP expects to be installed under the Horde directory? What? OK, fine, we’ll move it and clean it up with mod_rewrite later or something. Now http://my.server/horde/imp/ plays nice and I get a login screen. For whatever reason, despite what I set in the realm key for the entry I made in imp/config/servers.php isn’t getting appended like I thought it would. Fine, no big deal, it ends up logging me in. Disable Privoxy since… PHP is sending compressed for no apparent reason, would be my guess. Voila, you have mail n’shit.

IMP looks good. It has this big ole’ templates directory which contains a bunch of HTML fragments with the occasional PHP escape. I think the people that’ll be editing this HTML can handle that. They could with JSP, at least, though it’s been a while. No contact management; presumably need that other Horde component for that.

I’ll probably toss SquirrelMail and IMP by the boss tomorrow and see which he prefers. For now, I think I’ll try and sleep.

March 9, 2003

SquirrelMail on RH8

So I’m setting up a mail server again. This time my softwares of choice are Postfix, maildrop, Courier-IMAP, and SquirrelMail. I’m doing a “POP toaster” kind of configuration, where all user account information is kept outside of normal system authentication mechanisms. Just for the record, my previous setup was Qmail, VMailMgr, and SqWebMail. (I was using maildrop in this configuration as well, but IIRC it wasn’t exactly crucial, except for a ghetto way to have users set up web forwarding from SqWebMail. I was also using QmailAdmin in this setup. I’ll hopefully find something already written or write something myself to interact with userdb.)

I’ve got all the new setup going except SquirrelMail. It occurred to me that I should have been documenting my setup before, but since I’ve missed that I figured there’s no time like the present to start. I’m going to document my SquirrelMail setup as best I can. I’ll go back and document the setup of the other components later.
Grabbed the latest tarball off their site. SquirrelMail looks like another one of those PHP applications that basically expect you to extract the tarball into DocumentRoot or something. S’OK. My directory structure looks something like this:

/srv
  /www
    /default
      /root		# SquirrelMail tarball unpacked here.
        /data		# User preferences stored here.
      /mail-tmp		# Attachments and the like.

Those last two directories are mentioned in the SquirrelMail install file. They both need special permissions. I made mail-tmp owned by root, group apache, and mod 0730. They also mention that you should set up a cron job to clean out the mail-tmp directory. Here’s my /etc/cron.daily/mail-tmp-cleanup:

#!/bin/sh

/usr/sbin/tmpwatch 48 /srv/www/default/mail-tmp

Hopefully just that simple. The 48 above means “delete anything older than 48 hours.”

Then I ran config/conf.pl. The only option of note that I changed was the one that forces all user names to lowercase, I think. I’ve had problems with stuff that uses userdb and case sensitivity (wait for my maildrop discussion later).

Forgot to change DocumentRoot in /etc/httpd/conf/httpd.conf to point to /srv/www/default/root. Once I did that, started the httpd service, went to http://my.machine/ and got my SquirrelMail login. Login initially seems to be fine. Will do further testing (unknown users, sending mail, receiving mail, varying case in login) later.

For now: huzzah.

March 3, 2003

Playing with LISP


Warning: DOMDocument::loadHTML() [function.DOMDocument-loadHTML]: Tag super invalid in Entity, line: 10 in /srv/www/darkness.codefu.org/root/wordpress/wp-content/plugins/postxform/postxform.php on line 43

Warning: DOMDocument::loadHTML() [function.DOMDocument-loadHTML]: Unexpected end tag : p in Entity, line: 128 in /srv/www/darkness.codefu.org/root/wordpress/wp-content/plugins/postxform/postxform.php on line 43

Warning: DOMDocument::loadHTML() [function.DOMDocument-loadHTML]: Unexpected end tag : p in Entity, line: 155 in /srv/www/darkness.codefu.org/root/wordpress/wp-content/plugins/postxform/postxform.php on line 43

I assure you, it’s little more than playing. Ever since ardent came over and we did some number theory stuff together, I was kind of interested in working out some of the stuff we did with a program so the math wasn’t so burdensome. Additionally, I wanted to learn some LISP, and I’ve found the best way for me to learn a language is generally to jump in and do something with it. I’m doing things like calculating the order of integers in the set (I’m reaching with the formatting, here) Z * n . Here’s a demo of what I’ve written so far:

;; Demonstrate my (primep) function.
* (dotimes (n 10) (format t "~D: ~A~%" n (primep n)))
0: T
1: T
2: T
3: T
4: NIL
5: T
6: NIL
7: T
8: NIL
9: NIL
NIL
;; (factor) breaks a number down into pairs of
;; (prime-component exponent).
* (factor 64)
((2 6))
* (factor 67)
((67 1))
* (factor 16200)
((2 3) (3 4) (5 2))
;; I wrote (unfactor) to reverse (factor), just for
;; testing.  It was scary easy.
* (unfactor (factor 16200))
16200
;; (coprime) tests if all its arguments are coprime
;; relative to all other arguments.  Also scary easy.
* (coprime 24 25)
T
* (coprime 24 14)
NIL
* (coprime 24 25 (* 7 13))
T
;; (euler-phi) is an implementation of Euler's phi
;; function, which finds the number of integers less
;; than or equal to N that are coprime to N.
* (euler-phi 13)
12
* (euler-phi 21)
12
* (euler-phi 137)
136
* (euler-phi 138)
44
;; (z-mod-n), which computes Z mod N.  Stupid easy.
;; In fact, stupid period.  I may transform this into
;; a class so I can make operations on a subset of
;; Z like this.
* (z-mod-n 21)
(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20)
;; (multiplicative-group) finds the multiplicative
;; group of (z-mod-n N).  The multiplicative group
;; seems to be all numbers within (z-mod-n N) that
;; are invertible.
* (multiplicative-group 21)
(1 2 4 5 8 10 11 13 16 17 19 20)
;; (possible-orders) computes all possible orders for
;; any element in the multiplicative group of
;; (z-mod-n N).
* (possible-orders 21)
(1 2 4 3 6 12)
*
;; (order-of-integer) determines the order of the
;; integer A which must be in the multiplicative
;; group of (z-mod-n N).  (Hey, I didn't say I know
;; the meanings of this stuff, just that it's
;; part of number theory and kind of fun to do.)
(let ((n 10))
  (dolist (a (z-mod-n n))
    (format t "~D: ~D~%" a (order-of-integer a n))))
0: NIL
1: 1
2: NIL
3: 4
4: NIL
5: NIL
6: NIL
7: 4
8: NIL
9: 2
NIL
;; This one's for ardent, to check against his notes
;; if he'd like: the orders of all integers in
;; (multiplicative-group 21).
*
(let ((n 21))
  (mapcar (lambda (a)
	    (order-of-integer a n))
	  (multiplicative-group n)))
(1 6 3 6 2 6 6 2 3 6 6 2)

None of my LISP is pretty, I don’t think. I’m still not quite sure what functional programming entails, so I highly doubt I’m doing much if any of it. Furthermore, I haven’t taken the time to optimize any of this. I’ve barely taken the time to ensure that it’s correct (and I don’t know if it does some corner cases properly). Nevertheless, here’s my number theory LISP. This was all done in SBCL 0.7.13 on Linux/PPC.

Here’s a couple of questions I’ve got about LISP so far:

  • How the fuck do you step through a function in the SBCL debugger? I got as far as sticking some stuff like (declare (optimize (speed 0 size 0 debug 3))) in my code, and then inserting a (break) at the top, but once in the debugger nothing seemed to work? I was getting weird errors on (I think!) stuff like (sqrt n) where n = 7, with errors like The value 7 is not of type NUMBER. What the hell? I think I’m going to have to break down and ask #lisp. I apologize in advance.

  • Why do a lot of the examples I’m reading, particularly from Successful LISP use #'function instead of 'function? From some conversation on #lisp today they said that #'function refers to the function as a value or some such. (I’m actually too lazy to go lastlog it.) Yet everywhere in Successful LISP that they use #'function, I’ve been able to use just 'function. For example, in mapcar I can do stuff like (mapcar (lambda ...) ...) whereas the example in Successful LISP was (I think) (mapcar #'(lambda ...) ...). Both seem to work the same, at least in SBCL?

Maybe I’ll find some help on those. BTW, SBCL is way easy to build. I grabbed a 0.7.6 Linux/PPC SBCL binary off their SourceForge.net project page, the SRPM for 0.7.13, and after a little tweaking I built the RPM successfully (took two tries). A build of the RPM took about 1h. SBCL loads fast and seems to perform quite well. I’ve crashed it a few times I think (once just now with (primep 891927571939123), but maybe that was a bit too big) and I’m worried some of my debugging woes are due to bugs in SBCL, but I’m sure that’ll all work itself out in the end. Maybe they’re even PPC bugs. I’ve noticed that all the threading stuff seems to be available only on x86, not any other architectures. SBCL’s threading stuff might be experimental, in fact, but it exists at least. (I wonder if CMUCL has threading on PPC? I wonder if CMUCL has preemptive threading or just cooperative threading.)