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).

Reply via email to