BESKeys.cc

Go to the documentation of this file.
00001 // BESKeys.cc
00002 
00003 // This file is part of bes, A C++ back-end server implementation framework
00004 // for the OPeNDAP Data Access Protocol.
00005 
00006 // Copyright (c) 2004-2009 University Corporation for Atmospheric Research
00007 // Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
00008 //
00009 // This library is free software; you can redistribute it and/or
00010 // modify it under the terms of the GNU Lesser General Public
00011 // License as published by the Free Software Foundation; either
00012 // version 2.1 of the License, or (at your option) any later version.
00013 // 
00014 // This library is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 // Lesser General Public License for more details.
00018 // 
00019 // You should have received a copy of the GNU Lesser General Public
00020 // License along with this library; if not, write to the Free Software
00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 //
00023 // You can contact University Corporation for Atmospheric Research at
00024 // 3080 Center Green Drive, Boulder, CO 80301
00025  
00026 // (c) COPYRIGHT University Corporation for Atmospheric Research 2004-2005
00027 // Please read the full copyright statement in the file COPYRIGHT_UCAR.
00028 //
00029 // Authors:
00030 //      pwest       Patrick West <pwest@ucar.edu>
00031 //      jgarcia     Jose Garcia <jgarcia@ucar.edu>
00032 
00033 #include "config.h"
00034 
00035 #ifdef __cplusplus
00036 extern "C" {
00037 #include <sys/types.h>
00038 #include "regex.h"
00039 }
00040 #endif
00041 
00042 #include <cerrno>
00043 #include <cstring>
00044 #include <iostream>
00045 
00046 #if HAVE_UNISTD_H
00047 #include <unistd.h>
00048 #endif
00049 
00050 using std::endl ;
00051 using std::cout ;
00052 
00053 #include "BESKeys.h"
00054 #include "BESUtil.h"
00055 #include "BESInternalFatalError.h"
00056 
00073 BESKeys::BESKeys( const string &keys_file_name )
00074     : _keys_file( 0 ),
00075       _keys_file_name( keys_file_name ),
00076       _the_keys( 0 )
00077 {
00078     _keys_file = new ifstream( _keys_file_name.c_str() ) ;
00079     int myerrno = errno ;
00080     if( !(*_keys_file) )
00081     {
00082         char path[500] ;
00083         getcwd( path, sizeof( path ) ) ;
00084         string s = string("BES: fatal, cannot open initialization file ")
00085                    + _keys_file_name + ": " ;
00086         char *err = strerror( myerrno ) ;
00087         if( err )
00088             s += err ;
00089         else
00090             s += "Unknown error" ;
00091 
00092         s += (string)".\n" + "The current working directory is " + path + "\n" ;
00093         throw BESInternalFatalError( s, __FILE__, __LINE__ ) ;
00094     }
00095 
00096     _the_keys = new map<string,string>;
00097     try
00098     {
00099         load_keys();
00100     }
00101     catch(BESInternalFatalError &)
00102     {
00103         clean();
00104         throw;
00105     }
00106     catch(...)
00107     {
00108         clean() ;
00109         string s = (string)"Undefined exception while trying to load keys "
00110                    + "from bes configuration file " + _keys_file_name ;
00111         throw BESInternalFatalError( s, __FILE__, __LINE__ ) ;
00112     }
00113 }
00114 
00117 BESKeys::~BESKeys()
00118 {
00119     clean() ;
00120 }
00121 
00122 void
00123 BESKeys::clean()
00124 {
00125     if( _keys_file )
00126     {
00127         _keys_file->close() ;
00128         delete _keys_file ;
00129     }
00130     if( _the_keys )
00131     {
00132         delete _the_keys ;
00133     }
00134 }
00135 
00136 inline void
00137 BESKeys::load_keys()
00138 {
00139     char buffer[255];
00140     string key,value;
00141     while(!(*_keys_file).eof())
00142     {
00143         if((*_keys_file).getline(buffer,255))
00144         {
00145             if( break_pair( buffer, key, value ) )
00146             {
00147                 (*_the_keys)[key]=value;
00148             }
00149         }
00150     }
00151 }
00152 
00153 inline bool
00154 BESKeys::break_pair(const char* b, string& key, string &value)
00155 {
00156     if((b[0]!='#') && (!only_blanks(b)))//Ignore comments a lines with only spaces
00157     {
00158         register size_t l=strlen(b);
00159         if(l>1)
00160         {
00161             register int how_many_equals=0;
00162             int pos=0;
00163             for (register size_t j=0;j<l;j++)
00164             {
00165                 if(b[j] == '=')
00166                 {
00167                     how_many_equals++;
00168                     pos=j;
00169                 }
00170             }
00171 
00172             if(how_many_equals!=1)
00173             {
00174                 char howmany[256] ;
00175                 sprintf( howmany, "%d", how_many_equals ) ;
00176                 string s = string( "BES: invalid entry " ) + b
00177                            + "; there are " + howmany
00178                            + " = characters.\n";
00179                 throw BESInternalFatalError( s, __FILE__, __LINE__ );
00180             }
00181             else
00182             {
00183                 string s=b;
00184                 key=s.substr(0,pos);
00185                 BESUtil::removeLeadingAndTrailingBlanks( key ) ;
00186                 value=s.substr(pos+1,s.size());
00187                 BESUtil::removeLeadingAndTrailingBlanks( value ) ;
00188 
00189                 return true;
00190             }
00191         }
00192 
00193         return false;
00194     }
00195 
00196     return false;
00197 }
00198 
00199 bool
00200 BESKeys::only_blanks(const char *line)
00201 {
00202     int val;
00203     regex_t rx;
00204     string expr = "[^[:space:]]" ;
00205     val = regcomp( &rx, expr.c_str(), REG_ICASE ) ;
00206 
00207     if( val != 0 )
00208     {
00209         string s = (string)"Regular expression " + expr
00210                    + " did not compile correctly" ;
00211         throw BESInternalFatalError( s, __FILE__, __LINE__ ) ;
00212     }
00213     val = regexec( &rx, line, 0, 0, REG_NOTBOL ) ;
00214     if( val == 0 )
00215     {
00216         regfree( &rx ) ;
00217         return false ;
00218     }
00219     else
00220     {
00221         if( val == REG_NOMATCH )
00222         {
00223             regfree( &rx ) ;
00224             return true ;
00225         }
00226         else if( val == REG_ESPACE )
00227         {
00228             string s = "Execution of regular expression out of space" ;
00229             throw BESInternalFatalError( s, __FILE__, __LINE__ ) ;
00230         }
00231         else
00232         {
00233             string s = "Execution of regular expression has unknown problem" ;
00234             throw BESInternalFatalError( s, __FILE__, __LINE__ ) ;
00235         }
00236     }
00237 }
00238 
00253 string
00254 BESKeys::set_key( const string &key, const string &val )
00255 {
00256     map< string, string >::iterator i ;
00257     i = _the_keys->find( key ) ;
00258     if( i == _the_keys->end() )
00259     {
00260         (*_the_keys)[key] = val ;
00261         return val ;
00262     }
00263     (*i).second = val ;
00264     return val ;
00265 }
00266 
00279 string
00280 BESKeys::set_key( const string &pair )
00281 {
00282     string key ;
00283     string val ;
00284     break_pair( pair.c_str(), key, val ) ;
00285     return set_key( key, val ) ;
00286 }
00287 
00299 string
00300 BESKeys::get_key( const string& s, bool &found ) 
00301 {
00302     map<string,string>::iterator i;
00303     i=_the_keys->find(s);
00304     if(i!=_the_keys->end())
00305     {
00306         found = true ;
00307         return (*i).second;
00308     }
00309     else
00310     {
00311         found = false ;
00312         return "";
00313     }
00314 }
00315 
00322 void
00323 BESKeys::dump( ostream &strm ) const
00324 {
00325     strm << BESIndent::LMarg << "BESKeys::dump - ("
00326                              << (void *)this << ")" << endl ;
00327     BESIndent::Indent() ;
00328     strm << BESIndent::LMarg << "key file:" << _keys_file_name << endl ;
00329     if( _keys_file && *_keys_file )
00330     {
00331         strm << BESIndent::LMarg << "key file is valid" << endl ;
00332     }
00333     else
00334     {
00335         strm << BESIndent::LMarg << "key file is NOT valid" << endl ;
00336     }
00337     if( _the_keys && _the_keys->size() )
00338     {
00339         strm << BESIndent::LMarg << "    keys:" << endl ;
00340         BESIndent::Indent() ;
00341         Keys_citer i = _the_keys->begin() ;
00342         Keys_citer ie = _the_keys->end() ;
00343         for( ; i != ie; i++ )
00344         {
00345             strm << BESIndent::LMarg << (*i).first << ": "
00346                                      << (*i).second << endl ;
00347         }
00348         BESIndent::UnIndent() ;
00349     }
00350     else
00351     {
00352         strm << BESIndent::LMarg << "keys: none" << endl ;
00353     }
00354     BESIndent::UnIndent() ;
00355 }
00356 

Generated on 19 Feb 2010 for OPeNDAP Hyrax Back End Server (BES) by  doxygen 1.6.1