Wednesday, June 17, 2009

What to do when lazy matching and lookaheads won't work

You want to use regexes to search for a thing, then anything, then another thing.

Here's some example data to search through.

5678 Appletree Ave, MI
6701 Buttertown Road, MA
1337 Lolcat Lane, NM
5691 Appletree Way, MI
7832 Appletree Terrace, CT
4935 Appletree Motorway, MI

What you want to find here is any street named "Appletree" that is in Michigan.

The first thing most people try is .* or .+ but that matches the entire rest of the line which isn’t what they want. Using the regex "Appletree.*MI" will give you:
5678 Appletree Ave, MI
5691 Appletree Way, MI
7832 Appletree Terrace, CT
4935 Appletree Motorway, MI

You didn't want the Connecticut address in there. The easiest thing to do is to make the .* a lazy match by using ".*?" instead of ".*". This will give you what you want.

However, some parsers won't allow lazy matching. So what you can do is use a negated character class.

The first regex you might try is: Appletree[^M]+MI

In English, that’s match Appletree, then one or more characters that aren’t a capital M, then MI. This regex will miss Appletree Motorway but it's certainly better than not being able to search at all. At this point you could modify your regex to find something that wouldn't appear in the in between bit like the comma. The new regex would be: Appletree[^,]+,\sMI and it would find exactly what you wanted.

Wednesday, June 3, 2009

Setting up a tftp server in ubuntu

1. Get the necessary packages
# sudo apt-get install xinetd tftp tftpd

2. Create tftp config file for xinetd
# sudo emacs /etc/xinetd/tftp
copy this text into the file, replace the \t's with tabs and insert the IP of the interface you want to use:

service tftp
{
\tprotocol = udp
\tport = 69
\tsocket_type = dgram
\twait = yes
\tuser = nobody
\tserver = /usr/sbin/in.tftpd
\tserver_args = -s /tftpboot
\tdisable = no
\tbind = <IP of the interface you want to use>
}


3. Create /tftpboot directory, open permissions on it, and set its owner to the nobody user.
# sudo mkdir /tftpboot
# sudo chmod -R 777 /tftpboot
# sudo chown -R nobody /tftpboot


4. Restart xinetd
# sudo /etc/init.d/xinetd restart

5. Test
# touch /tftpboot/testfile
# chmod 777 /tftpboot/testfile
# ls -l /tftpboot

note the time/date modified on testfile
# cd /tftpboot
# tftp <IP of the interface you ran tftp on>
#tftp> put testfile
#tftp> quit
# ls -l /tftpboot

if the time/date modified have changed then you have successfully overwritten the file.