Archive for January, 2007


After many hours trying to figure this out, I finally found a way to enable spamassassin on a Plesk 8 box without buying the PowerPack or the SpamAssassin plugin. For the record, SpamAssassin comes installed with Plesk 8 in every configuration, it’s just not “enabled” for the mail server, Qmail.

My setup: Plesk 8.0 on Fedora Core 4.

This is based on the HOW-TO: setup a PLESK Dedicated Server tutorial.

Special thanks to the all powerful Atomic Rocket Turtle!

First, login to your server with SSH and become root.

Since Plesk moves everything around on us and breaks easily when you mess around, you need to configure yum so you can grab some Plesk pre-configured RPMS:

yum install lynx
lynx -source http://3es.atomicrocketturtle.com/installers/atomic.sh | sh

# now build your qmail-scanner-queue.pl file:
/usr/bin/qmail-scanner-reconfigure

Until I figure out how to make qmail-scanner play nice with drweb antivirus, you will need to uninstall it – who uses “DrWeb” anyway? Also, you’ll want to install qmail-scanner and clamd. qmail-scanner allows you to break into the qmail process and scan messages for spam, viruses, etc before delivery. clamd is the antivirus scanning daemon for ClamAV.

yum remove drweb-qmail drweb
yum install qmail-scanner clamd

Hit ‘y’ for yes – you want to download and install all the dependencies.

Now you should be all setup! Whew! That was easy.

Now you should send yourself the EICAR test virus to see if ClamAV is working.

Check /usr/local/psa/var/log/maillog to see if spamd is checking your mail (spamassassin):

Jan 23 17:42:42 216-55-149-29 spamd[2974]: connection from localhost.localdomain [127.0.0.1] at port 36138
Jan 23 17:42:42 216-55-149-29 spamd[2974]: info: setuid to qscand succeeded
Jan 23 17:42:42 216-55-149-29 spamd[2974]: Creating default_prefs [/var/spool/qscan/.spamassassin/user_prefs]
Jan 23 17:42:42 216-55-149-29 spamd[2974]: Created user preferences file: /var/spool/qscan/.spamassassin/user_prefs
Jan 23 17:42:42 216-55-149-29 spamd[2974]: processing message <00m94g5gf2f73f9b@users.sourceforge.net> for qscand:10003.
Jan 23 17:42:43 216-55-149-29 spamd[2974]: clean message (-0.0/7.0) for qscand:10003 in 1.4 seconds, 394 bytes.
Jan 23 17:42:43 216-55-149-29 spamd[2974]: result: .  0 - NO_RECEIVED,NO_RELAYS scantime=1.4,size=394,mid=<00m94g5gf2f73f9b@users.sourceforge.net>,autolearn=ham

And you can check /var/log/clamav/clamd.log to make sure ClamAV AntiVirus is working:

Tue Jan 23 20:42:51 2007 -> Portable Executable support enabled.
Tue Jan 23 20:42:51 2007 -> Detection of broken executables enabled.
Tue Jan 23 20:42:51 2007 -> Mail files support enabled.
Tue Jan 23 20:42:51 2007 -> Mail: Recursion level limit set to 64.
Tue Jan 23 20:42:51 2007 -> OLE2 support enabled.
Tue Jan 23 20:42:51 2007 -> HTML support enabled.
Tue Jan 23 20:42:51 2007 -> Self checking every 1800 seconds.
Tue Jan 23 20:43:30 2007 -> /tmp/mkt_qs.5057-1169603010/eicar.com: Eicar-Test-Signature FOUND
<strong>Tue Jan 23 20:46:35 2007 -> /var/spool/qscan/tmp/216-55-149-29.dedicated.abac.net11696031957636239/eicar.com: Eicar-Test-Signature FOUND</strong>

You can tell ClamAV to update it’s virus database twice a day like this:

freshclam -d -c 2

Wow – so today I figured out (after yelling for a short while) that Flash’s Actionscript 2 does not make copies of objects, it makes references. If you don’t know the difference you probably won’t benefit from this article, but here’s an analogy anyway. Consider this code:

var date1 = new Date(2007,0,1); // January 1, 2007 00:00:00
var date2 = date1;
var date2.setMonth(1); // Febuary 1, 2007 00:00:00

If you’re anything like me you would expect “date1” to still be “January 1, 2007” and “date2” to be “Febuary 1, 2007” – NOPE, WRONG! Stupid Actionscript tries to save RAM by automatically making references, or “pointers” (or “nicknames”) to Objects instead of copying them – this is not a real bad idea for Actionscript 1 I guess – since it’s a n00b language, but I can extend dynamic classes in AS2 – it’s an OOP language, so it should behave like one! So, since there’s no character to make a reference (in PHP you can use $date2 =& $date1), you can’t not make it a reference. To fix this problem I searched the net a bit and ran across an Object prototype that adds a clone() method to it. Unfortunately the clone method didn’t work for Date object, so naturally I was forced to make it work :(. Well, here it is – just paste this code somewhere in the beginning of your FLA or in an AS file that is included:

/*
************************************************************
Object.clone
by  : Steve Kamerman (kamermans at teratechnologies.net)
Blog: http://www.teratechnologies.net/stevekamerman
Ver : 1.0
Date: 13Jan2007
************************************************************
Object.clone creates a perfect copy of an object
Modified from R.Arul Kumaran's version to support Date Objects
*/


Object.prototype.clone = function() {
  if (this instanceof Array) {
    var to = [];
    for (var i = 0; i<this.length; i++) {
      to[ i] = (typeof (this[ i]) == "object") ? this[ i].clone() : this[ i];
    }
  }else if(this instanceof Date){
    var to = new Date(this.getTime());
  }else if (this instanceof XML || this instanceof MovieClip) {
  // can't clone this so return null
  var to = null;
  trace("Object.clone won't work on MovieClip or XML");
  } else {
    var to = {};
    for (var i in this) {
      to[ i] = (typeof (this[i ]) == "object") ? this[ i].clone() : this[ i];
    }
  }
  return(to);
}
ASSetPropFlags(Object.prototype, ["clone"], 1);
/*
Usage:-
var date1 = new Date(2007,0,1); // January 1, 2007 00:00:00
var date2 = date1.clone();
var date2.setMonth(1);

// now date2 contains the Date Object for Febuary 1, 2007 00:00:00
// changing date2 will not affect date1
*/

I hope you like it!

Stupid osCommerce is still living in the dark ages, using things like register_globals and $HTTP_POST_VARS – come on guys – get with the program! Following my theme of being forced to fix every program I try to use, I have patched osCommerce 2.2 Milestone 2 Update 060817 to work with PHP 5. Luckily this is an easy fix. First download it from the link above and install the Register Globals Patch (look for VV 1.5 – ZIP Archive).

Now that we have that issue solved we just need to fix the $HTTP_*_VARS issue – these are old school PHP3 variables that were included in PHP4 for compatibility.

Copy this and put it in a file called php5fix.php in your catalog/includes directory:

<?php
// PHP5 Fix by Steve Kamerman, http://www.teratechnologies.net/stevekamerman

$phpversion = explode('.', phpversion());
if((int) $phpversion[0] >= 5){
// PHP 5 has no idea what this crap is
$HTTP_GET_VARS = &$_GET;
$HTTP_POST_VARS = &$_POST;
$HTTP_REQUEST_VARS = &$_REQUEST;
$HTTP_SESSION_VARS = &$_SESSION;
$HTTP_COOKIE_VARS = &$_COOKIE;
$HTTP_SERVER_VARS = &$_SERVER;
$HTTP_FILES_VARS = &$_FILES;
$HTTP_ENV_VARS = &$_ENV;
}
?>

Now edit catalog/admin/includes/application_top.php and add this just below the comments at the top:

// PHP5 fix
require_once("../includes/php5fix.php");

Edit catalog/includes/application_top.php and add this just below the comments at the top:

// PHP5 fix
require_once("includes/php5fix.php");

If you haven’t completed the installation yet, do this too:
Edit catalog/install/application.php and add this just below the comments at the top:

// PHP5 fix
require_once("../includes/php5fix.php");

Now you should be good to go! I’ll take a bow and pat myself on the back now – have a nice day 😀

P.S. I suppose I could fix up a fresh installation and provide you with a link to download it from if you want. Somebody please email me if you want it, otherwise I’m wasting my time.

After many many hours hunched over my keyboard, I have finished a major revamp of the Tera-WURFL code. Here's what's new:

Completely rewrote the error logging system and verified it's operation after a bug was discovered (thanks Neil!)
Added many features to the web administration console – seriously – check out the online demo!
Changed default DATADIR to the included 'data' directory
Completely rewrote the README file to include detailed installation instructions and other useful info
Optimized the clean installation process – now Tera-WURFL has a brain!
Included the current stable release of the wurfl.xml file so you don't need to download it
Included database statistics, log file monitoring and global configuration in new web interface
Changed default log level to LOG_WARNING instead of LOG_ERR
Described in great detail the purpose of the different database tables

If you are using Tera-WURFL 1.4.3 or earlier I would highly recommend that you upgrade to 1.4.4 due to some fairly significant bugs!

Tera-WURFL Website

UPDATE 25Feb2008 – Adobe has published the recommended workaround for this problem.

This is another major release – I rewrote some of the code with some inspiration from Zelph.com’s onDOMload as suggested by Geoff Stearns, Author of SWFObject. I have now optimized the code to the point where all you need to do is include it in the head of your document and as the page loads, each object will be fixed, so by the time the page is done loading, everything is fixed automatically!

———EDIT 19Jan2007———
I found yet another IE bug related to this topic. After a page is cached by IE and reloaded, the SWF is loaded before it’s embedded, so any callback functions the the SWF tries to setup when it loads (like the JS->Flash ExternalInterface code) will fail with an error “objectID” is undefined. Then when you try to use the callback function you get Object doesn’t support this property or method because the functions didn’t get assigned to the Flash object properly.

To fix this error you need to put this line above your SWFObject code (or above your <object> tag):

window["objectid"] = new Object();

Here’s an example document:
http://devel.teratechnologies.net/swfformfix/extinterface-swfformfix2.php

You can download SWFFormFix2 Here:
http://devel.teratechnologies.net/swfformfix/swfformfix2.js

You can see the nicely formatted and highlighted source code here:
http://devel.teratechnologies.net/swfformfix/swfformfix2.js.source