parsing tnsnames.ora with perl

For the last several hours I’ve been looking for some perl code that would let me parse a tnsnames.ora file. The plan is to read in the database connect data and create an LDIF file to load the OracleContext on my LDAP directory server.

What I finally found was this, which worked once I fixed a small typo (the file handle first defined as <FH> is later on mistakenly rendered <fh> — no doubt the author was used to working on case-insensitive Windows, the bad news is, of course, that perl is internally case sensitive for environment strings like file handles no matter what the platform. A corrected copy of the script can be found here.

The command syntax for it is:

ora_tns_parser.pl [format] [filename]

The format variable is explained in the script comments, but of the four types the one labeled ALL is what I’ve decided to work with for now. This outputs the data in a

oraclesid:(connectstring)

format, which is just what I’ll need.

What I’ll do next is take this code and incorporate it into a “tns2ldif.pl” script that will be able to create the requisite orclService objects for resolving Oracle database connection information. Eventually I’ll also write a simple perl cgi script that will allow others to easily add, update or delete service objects as the need arises.

Note that this script is ultra sensitive to any deviation from the “standard” tnsnames.ora format. I got lucky on my first round because what I was working with was an older file that had been carefully built to strictly meet that standard. When I got into work and tried it with my latest working file I kept getting an error that “line 7” had a syntax problem. After several hours of trial and error I decided to just do a diff and begin tacking newer material one block at a time. In my case the problem was a few lines that used the format “examplesid = ( DESCRIPTION =” on the same line, rather than the prettified

examplesid =
      ( DESCRIPTION =
         (ADDRESS =

Fixing up the lines to meet the latter format got the script working again as required.