Sep 302012

Email is everywhere. You may not know immediately if your web site is down but you’ll almost always know if your email isn’t working.  The ability to send and receive email 24×7 is critical to the success of any business. This means you need a product which is reliable, scalable, and affordable. There are not many mail server products on the market which meet that criteria. However, Smartermail by is one such product. Year after year Smartertools has evolved with more features and better security. The latest version of Smartermail is their best product to date.
Smartermail 10 GUI
However, they inadvertently introduced a small design flaw in the administration GUI. Finding disabled domains is a real pain. If your Smartermail deployment only has 5-10 domains then you probably haven’t even noticed this. However if your organization relies on Smartermail to host hundreds or even thousands of mail domains then you are already well aware of this design oversight.  Of course one can simply scroll through the domain list looking for Disabled status which is clearly marked in red however this is a daunting task for large deployments. Curiously in legacy versions of Smartermail you could easily sort your entire domain list by enabled or disabled status.

Because Smartermail stores it’s domains in a logical fashion, it is easy to programmatically access the config files and determine whether or not a domain is enabled. For example C:\Smartermail\Domains would contain all the domains of your Smartermail instance.  Each mail domain will be stored as subdirectory of this directory and the individual domain settings will be stored in file called domainconfig.xml. Contained in this file is a node called “isEnabled”.  As one might expect if the domain is enabled the value will be True whereas if the domain is disabled then the value will be False. Here is a a snippet of what it looks like.

So here’s where a bit of programming saves the day. Using C# and ASP.NET I created a simple console application which will read the Smartermail domains folder,  check the domainconfig.xml of each domain on the server, and then output the results to a log file. One complication with this is that Smartermail may not have been installed in the default location so I am using a simple xml config file for my program which specifies the path to the domains folder along with the path where I want the log file to saved.


<?xml version="1.0" encoding="utf-8"?>\r\n<MyConfig>\r\n  <DomainsPath>H:\Smartermail\Domains</DomainsPath>\r\n  <LogPath>H:\Temp\disabled_log.txt</LogPath>\r\n</MyConfig>

\r\n\r\nHere’s how my program looks:\r\n\r\n

namespace checkDisabled\r\n{\r\n    class Program\r\n    {\r\n        public static string strLogPath;\r\n        public static string strDomainsPath;\r\n                \r\n        static void Main(string[] args)\r\n        {\r\n            string path = System.IO.Path.GetFullPath(@"checkDisabled.xml");\r\n            XmlDocument xmlDoc = new XmlDocument();\r\n            xmlDoc.Load(path);\r\n            XmlNodeList DomainsPath = xmlDoc.GetElementsByTagName("DomainsPath");\r\n            XmlNodeList LogPath = xmlDoc.GetElementsByTagName("LogPath");\r\n\r\n            strDomainsPath = DomainsPath[0].InnerXml;\r\n            strLogPath = LogPath[0].InnerXml;\r\n\r\n            checkFolders();\r\n        }\r\n\r\n        static private void checkFolders()\r\n     \r\n        static private void checkDisabled(string sDomain, string sPath)\r\n     \r\n        static private void disabledLog(string strLine)\r\n    }\r\n}\r\n

\r\n\r\nI create a subroutine called “checkFolders” which reads the Smartermail domains folder and then iterates through any subdirectory. To help keep things clean I will use a another subroutine to actually read domainconfig.xml file.\r\n\r\n

static private void checkFolders()\r\n{\r\n    string[] folders = System.IO.Directory.GetDirectories(strDomainsPath);\r\n    string strDomainName = "";\r\n    string strConfigFile = "";\r\n\r\n    Console.WriteLine("Checking " + strDomainsPath + " for disabled domains.");\r\n\r\n    foreach (string sDir in folders)\r\n    {\r\n        strConfigFile = sDir + @"\domainConfig.xml";\r\n        strDomainName = sDir.Substring(strDomainsPath.Length + 1);\r\n        if (File.Exists(strConfigFile))\r\n            checkDisabled(strDomainName, strConfigFile);\r\n    }\r\n\r\n    Console.WriteLine("Done.");\r\n}

\r\n\r\nHere is the code I use to read the domainconfig.xml file. If a domain is identified as being disabled then I write a line to the screen as well as the log file.\r\n

static private void checkDisabled(string sDomain, string sPath)\r\n{\r\n    XmlDocument xmlDoc = new XmlDocument();\r\n    xmlDoc.Load(sPath);\r\n    XmlNodeList isEnabled = xmlDoc.GetElementsByTagName("isEnabled");\r\n\r\n    if (!Convert.ToBoolean(isEnabled[0].InnerXml))\r\n    {\r\n        Console.WriteLine("Disabled: " + sDomain);\r\n        disabledLog(sDomain);\r\n    }\r\n}\r\n

\r\n\r\nWriting the output to the log file is straight forward. I check if the log file exists and if it doesn’t then just create an empty file.\r\n\r\n

static private void disabledLog(string strLine)\r\n{\r\n    if (!File.Exists(strLogPath))\r\n        using (StreamWriter sw = File.CreateText(strLogPath))\r\n            sw.WriteLine("");\r\n\r\n    using (StreamWriter sw = File.AppendText(strLogPath))\r\n        sw.WriteLine(strLine);\r\n}

\r\n\r\nRunning the program from the command line we see the results.


H:\temp>checkdisabled\r\nChecking H:\Smartermail\domains for disabled domains.\r\nDisabled:\r\nDisabled:\r\nDone.\r\n\r\nH:\temp>

Taking it a step further we could use Windows Task Scheduler run it on a weekly or daily basis and with only a small tweak we could code emailing the log file so that we didn’t even have to login to the server to check the disabled domains.

Peter Viola

Creative, customer focused, results oriented, Senior Web Systems Engineer who enjoys providing the highest level of customer service supporting complex Windows hosting solutions. MCITP, MCSA, MCTS

More Posts - Website