Crontab

Engineering approach

XML and DTD

What you see below is the dtd file and the xml representation for an crontab file. The dtd tutorial I was using for this to come true is on w3schools. The information about the crontab file was taken from FreeBSD online man.

  • The extended tag is maybe a bit of exaggeration, also the ln attribute
  • You need to additionaly run checks in your code to fully validate the xml file. Before do the steps below:
          • Replace all occurences of Jan,Feb,Mar,…,Dec with the corresponding numbers 1..12
          • Replace all occurences of Sun,Mon,…,Sat with 0…6 (Ok, for Sun you can use 0 or 7)
          • Expand all ranges (pay attention to constructs like 10-30/2) to single values
          • Expand the special tag into a real time tag (obviously not the reboot one)
          • Check for valid characters in the text.
          • Autocorrect multiple commas, dashes etc. ?
<?xml version="1.0"?>
<!DOCTYPE crontab [
<!ELEMENT crontab (extended*,path?,extended*,home?,extended*,shell?,extended*,mailto?,extended*,entry*,extended*)>
<!ELEMENT entry ((special|time),user?,command)>
<!ELEMENT time (minute?,hour?,dayofmonth?,month?,dayofweek?)>
<!ELEMENT special EMPTY>
<!ELEMENT shell EMPTY>
<!ELEMENT path EMPTY>
<!ELEMENT command (#PCDATA)>
<!ELEMENT home (#PCDATA)>
<!ELEMENT user (#PCDATA)>
<!ELEMENT mailto (#PCDATA)>
<!ELEMENT minute (#PCDATA)>
<!ELEMENT hour (#PCDATA)>
<!ELEMENT dayofmonth (#PCDATA)>
<!ELEMENT month (#PCDATA)>
<!ELEMENT dayofweek (#PCDATA)>
<!ELEMENT extended (#PCDATA)>
<!ATTLIST crontab src CDATA "/etc/crontab">
<!ATTLIST crontab ip CDATA "127.0.0.1">
<!ATTLIST crontab name CDATA "localhost">
<!ATTLIST crontab sys CDATA "unknown">
<!ATTLIST shell use CDATA "/bin/sh">
<!ATTLIST path use CDATA "/usr/bin:/bin">
<!ATTLIST shell ln CDATA #IMPLIED>
<!ATTLIST path ln CDATA #IMPLIED>
<!ATTLIST home ln CDATA #IMPLIED>
<!ATTLIST mailto ln CDATA #IMPLIED>
<!ATTLIST entry ln CDATA #IMPLIED>
<!ATTLIST extended ln CDATA #IMPLIED>
<!ATTLIST special interval (reboot|yearly|annually|monthly|weekly|daily|midnight|hourly) #REQUIRED>
]>
<crontab src="/etc/crontab" ip="192.168.2.73" name="poseidon" sys="FreeBSD">
    <extended ln="4"># This specifies an alternate path from the default</extended>
    <path ln="5" use="/usr/bin:/bin:/sbin:/usr/sbin"/>
    <shell ln="6" use="/bin/bash"/>
    <extended ln="8"># The next line defines a variable</extended>
    <extended ln="9">SOME_VARIABLE=56</extended>
    <home ln="10">/home/killroy</home>
    <mailto ln="15">lokutus@b.org</mailto>
    <entry ln="18">
        <special interval="daily"/>
        <user>admin</user>
        <command>su -l hogfather /bin/bang &gt; /var/log/hohohooo.log</command>
    </entry>
    <entry ln="20">
        <time>
            <minute>3,25,37-41,58</minute>
            <hour>0-5/2,17,21-23</hour>
            <dayofmonth>5,13,17-23/3,28,31</dayofmonth>
            <month>5-11/2</month>
            <dayofweek>0,1-5/2,6,7</dayofweek>
        </time>
        <command>mail -s &quot;It&apos;s 10pm&quot; joe%Joe,%%Where are your kids?%</command>
    </entry>
</crontab>

Perl code

Here you will see some perl code for handling those xml entries.

  • Some code to handle the conversion of days/month names to numbers and expanding of the allowed range formats.

ToDo

  • Add a lng attribute to the crontab tag to indicate the language in which the month names and names of day of week are.

Scientific approach

XML and XSD

This is something to be done later. But with xsd you can check much better the values. Alas you need a different xml structure. Additionaly you can do nice things with xslt transformations. And maybe XForms can be used to input values from web ?

Ideas

Maybe a interesting idea would be to have a crontab (or any other configuration file for that matter) modified on a central host. Then encrypt it with the public key and send it to host(s) which shall be configured. Those hosts decrypt the configuration with the private key, install the file (converting it to ini format perhaps or as conf file) and restart the appropriate daemons. Would be interesting to try it out for let's say inetd.conf. Or instead of encryption just sign it and distribute.

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-Share Alike 2.5 License.