THANKS Stephane.
Cool stuff... But I don't like lot's of lines of code so I just went ahead
and did it in Python. Here's some code for the curious:
-------------------------------------------------------------------
#!/usr/bin/env python
""" file=login.py Purpose: present a login form. """
import cgi, os, re
import myconstants as con
form = cgi.FieldStorage()
def parseNet8services():
"""Parse tnsnames.ora, return list of service labels."""
fHdl = open(con.tnsnames_file) # Get a handle to the file...
sList = fHdl.read() # Read file into a string...
sList = re.sub("\(.*\n","",sList) # Remove "(" to end of line...
sList = re.sub("\)","",sList) # Clean up ")"...
sList = re.sub(" ","",sList) # Remove spaces...
sList = re.sub("\n","",sList) # Remove carriage returns...
sList = re.sub("=$","",sList) # Remove last "=" character...
sList = sList.split("=") # Create Python list of labels...
fHdl.close() # Close the file...
return sList # Return the list...
. . .
"""Present an HTML option list for the possible databases to access."""
dblist = parseNet8services()
optionText = ""
for db in dblist:
optionText+="""<OPTION value "%s">%s</OPTION>""" %(db,db)
. . .
def main():
. . .
-------------------------------------------------------------------
Steve Orr,
Oracle DBA and part-time Python evangelist. ;-)
Bozeman, Montana
-----Original Message-----
Sent: Tuesday, November 12, 2002 12:58 PM
To: Multiple recipients of list ORACLE-L
Importance: High
"Orr, Steve" wrote:
>
> Anyone have a ready-made regular expression to parse out the net8 service
> name labels from tnsnames.ora? Perl is OK. What I'm looking for is a way
to
> get a list of possible connections from tnsnames.ora. For example, from
the
> below I just want a regular expression which returns label1 and label2...
> --------------------------------------------------------
> label1 = (description_list=
> (description=
> (address=(...))
> (connect_data=(...)))
> (description=
> (address=(...))
> (connect_data=(...)))
> )
>
> label2 = (description_list=
> (description=
> (address=(...))
> (connect_data=(...)))
> (description=
> (address=(...))
> (connect_data=(...)))
> )
> --------------------------------------------------------
>
> AtDhVaAnNkCsE !!!!!!!!
>
> Steve Orr
> Bozeman, Montana
> --
> Please see the official ORACLE-L FAQ: http://www.orafaq.com
> --
Steve,
You may be interested by one of the numerous things our webmaster forgot
to post on the Oriole site :
==============CUT HERE=====================
/*
========================================================================
*
*
* tnsparse.c - Copyright (c) Oriole Software, 2001
*
* Downloaded from http://www.oriole.com
*
* Reads a tnsnames.ora file on its standard input and writes
* tnsalias<tab>host<tab>sid
* to its standard output.
*
* This can be used for a number of things:
* o to generate a clean inventory and load it into, say, a
spreadsheet
* or build a HTML page. This can easily be done with the
following
* awk program :
*
* BEGIN {
* print "<HTML>";
* print "<HEAD>";
* print " <TITLE>Oracle databases</TITLE>";
* print "</HEAD>";
* print "<BODY TEXT=BLACK BGCOLOR=WHITE>";
* print "<CENTER>";
* print "<TABLE WIDTH=\"80%\">";
* print "<TR BGCOLOR=NAVY>";
* print "<TD><B><FONT COLOR=GOLD>TNS
Alias</FONT></B></TD>";
* print "<TD><B><FONT COLOR=GOLD>Host</FONT></B></TD>";
* print "<TD><B><FONT COLOR=GOLD>Service
Name</FONT></B></TD>";
* print "</TR>";
* }
* {
* if (NR %2 == 1)
* {
* print "<TR BGCOLOR=LIGHTCYAN>";
* }
* else
* {
* print "<TR BGCOLOR=LIGHTSKYBLUE>";
* }
* for (i = 1; i <= NF; i++)
* {
* printf("<TD>%s</TD>\n", $i);
* }
* print "</TR>";
* }
* END {
* print "</TABLE>";
* print "</CENTER>";
* print "</BODY>";
* print "</HTML>";
* }
*
* o to clean-up (ordering by alphabetical order, say) or merge
easily
* (removing duplicate entries) existing tnsnames.ora file.
* Assuming that you only have TCP/IP and are always using the
same
* port (say 1526), a clean tnsnames.ora file can easily be
* regenerated feeding the (cooked) output of tnsparse into an
awk
* programme such as :
*
* {
* printf("%s=\n", $1);
* printf("(DESCRIPTION =\n");
* printf(" (ADDRESS_LIST =\n");
* printf(" (ADDRESS =\n");
* printf(" (COMMUNITY = your_company.world)\n");
* printf(" (PROTOCOL = TCP)\n");
* printf(" (Host = %s)\n", $2);
* printf(" (port = 1526)\n");
* printf(" )\n");
* printf(" ) \n");
* printf(" (CONNECT_DATA =\n");
* printf(" (SID = %s)\n", $3);
* printf(" (GLOBAL_NAME = %s.WORLD)\n", $3);
* printf(" )\n");
* printf(") \n");
* printf("\n");
* }
*
*
========================================================================
*
* To build tnsparse :
* cc tnsparse.c -o tnsparse
*
* To use it :
* tnsparse < $ORACLE_HOME/network/admin/tnsnames.ora >
tnslist.txt
*
* Tries to support both pre and post 8.1 formats.
*
* Note that the program is a bit too sophisticated for what it
does.
* We hope that it will make it easier for you to modify it and
extract
* more data (for instance, the listener port when using TCP/IP) to
suit
* your needs.
*
========================================================================
*
* This program for Oracle database administration is free software;
you
* can redistribute it and/or modify it under the terms of the GNU
General
* Public License as published by the Free Software Foundation;
either
* version 2 of the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
========================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define STACK_SIZE 100
#define LINE_LEN 1024
#define TNS_LEN 100
#define HOST_LEN 512
#define SID_LEN 100
#define MAX_LEN 512
#define KEYWORDS 8
#define KW_ADDRESS 0
#define KW_ADDRESS_LIST 1
#define KW_CONNECT_DATA 2
#define KW_DESCRIPTION 3
#define KW_DESCRIPTION_LIST 4
#define KW_HOST 5
#define KW_SERVICE_NAME 6
#define KW_SID 7
#define KW_IGNORED KEYWORDS
static char *G_stack[STACK_SIZE];
static short G_st = 0;
static char G_tns_alias[TNS_LEN];
static char G_host[HOST_LEN];
static char G_service[SID_LEN];
static char *G_kw[KEYWORDS+1] = {"ADDRESS",
"ADDRESS_LIST",
"CONNECT_DATA",
"DESCRIPTION",
"DESCRIPTION_LIST",
"HOST",
"SERVICE_NAME",
"SID",
NULL};
static short which_kw(char *string)
{
short i = KW_IGNORED;
if (string)
{
G_kw[i] = string;
i = 0;
while (strcasecmp(string, G_kw[i]))
{
i++;
}
}
return(i);
}
static char check(short kw)
/*
* A bit of an overkill, but I am a paranoid.
*/
{
short prev;
if (0 == G_st)
{
return(0);
}
prev = which_kw(G_stack[G_st - 1]);
switch (kw)
{
case KW_HOST :
return(KW_ADDRESS == prev);
case KW_SERVICE_NAME :
case KW_SID :
return(KW_CONNECT_DATA == prev);
default :
return(0);
}
}
static void store(char *identifier)
{
if (identifier)
{
if (G_stack[G_st] != NULL)
{
free(G_stack[G_st]);
}
G_stack[G_st] = strdup(identifier);
}
}
static char *peek(void)
{
if (G_st)
{
return(G_stack[G_st]);
}
return(NULL);
}
static void output(void)
{
printf("%s\t%s\t%s\n", G_tns_alias, G_host, G_service);
G_host[0] = '\0';
G_service[0] = '\0';
}
main()
{
char line[LINE_LEN];
char identifier[MAX_LEN];
char *p;
short kw;
short i;
char pending = 0;
/*
* Initialize
*/
for (i = 0; i < STACK_SIZE; i++)
{
G_stack[i] = NULL;
}
G_tns_alias[0] = '\0';
G_host[0] = '\0';
G_service[0] = '\0';
while (fgets(line, LINE_LEN, stdin))
{
if (line[0] != '#')
{
p = line;
i = 0;
while (*p != '\n')
{
switch(*p)
{
case '=' :
identifier[i] = '\0';
store(identifier);
if (0 == G_st)
{
if (pending)
{
output();
pending = 0;
}
strncpy(G_tns_alias, identifier, TNS_LEN);
G_tns_alias[TNS_LEN-1] = '\0';
pending = 1;
}
i = 0;
break;
case ' ' :
case '\t' :
break;
case '(' :
G_st++;
break;
case ')' :
identifier[i] = '\0';
switch (kw = which_kw(peek()))
{
case KW_HOST :
if (check(kw))
{
strncpy(G_host, identifier,
HOST_LEN);
G_host[HOST_LEN-1] = '\0';
if (G_service[0] != '\0')
{
output();
pending = 0;
}
else
{
pending = 1;
}
}
break;
case KW_SERVICE_NAME :
case KW_SID :
if (check(kw))
{
strncpy(G_service,
identifier,
SID_LEN);
G_service[SID_LEN-1] = '\0';
if (G_host[0] != '\0')
{
output();
pending = 0;
}
else
{
pending = 1;
}
break;
default :
break;
}
}
G_st--;
i = 0;
break;
default :
identifier[i] = *p;
i++;
break;
}
p++;
}
}
}
if (pending)
{
output();
}
/*
* Do things cleanly, this is not Java ...
*/
i = 0;
while (G_stack[i] != NULL)
{
free(G_stack[i++]);
}
exit(0);
--
Regards,
Stephane Faroult
Oriole Software
--
--
Please see the official ORACLE-L FAQ: http://www.orafaq.com
--
Author: Orr, Steve
INET: [EMAIL PROTECTED]
Fat City Network Services -- 858-538-5051 http://www.fatcity.com
San Diego, California -- Mailing list and web hosting services
---------------------------------------------------------------------
To REMOVE yourself from this mailing list, send an E-Mail message
to: [EMAIL PROTECTED] (note EXACT spelling of 'ListGuru') and in
the message BODY, include a line containing: UNSUB ORACLE-L
(or the name of mailing list you want to be removed from). You may
also send the HELP command for other information (like subscribing).