login_info.cpp

Go to the documentation of this file.
00001 /*****************************************************************************\
00002 *                                                                             *
00003 *  Name   : login_info                                                        *
00004 *  Author : Chris Koeritz                                                     *
00005 *                                                                             *
00006 *******************************************************************************
00007 * Copyright (c) 2008-$now By Author.  This program is free software; you can  *
00008 * redistribute it and/or modify it under the terms of the GNU General Public  *
00009 * License as published by the Free Software Foundation; either version 2 of   *
00010 * the License or (at your option) any later version.  This is online at:      *
00011 *     http://www.fsf.org/copyleft/gpl.html                                    *
00012 * Please send any updates to: fred@gruntose.com                               *
00013 \*****************************************************************************/
00014 
00015 #include "login_info.h"
00016 
00017 #include <basis/function.h>
00018 #include <basis/log_base.h>
00019 #include <data_struct/static_memory_gremlin.h>
00020 #include <opsystem/byte_filer.h>
00021 #include <opsystem/filename.h>
00022 #include <opsystem/ini_config.h>
00023 
00024 #include <stdio.h>
00025 
00026 #define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger(), filename(portable::application_name()).basename().raw() + " " + s)
00027 
00029 
00030 // select a default config file based on platform considerations.
00031 SAFE_STATIC(istring_object, database_login_info::freetds_config_file,
00032 #ifdef EMBEDDED_BUILD
00033     ("/etc/config/freetds.conf")
00034 #else
00035     ("/usr/local/etc/freetds.conf")
00036 #endif
00037 );
00038 
00039 database_login_info::database_login_info(const istring &db_section_in)
00040 : db_section(db_section_in)
00041 {
00042   reset();
00043 }
00044 
00045 database_login_info::~database_login_info() { reset(); }
00046 
00047 bool database_login_info::identical(const database_login_info &to_compare)
00048 {
00049   return (user_name == to_compare.user_name)
00050       && (password == to_compare.password)
00051       && (db_host == to_compare.db_host)
00052       && (db_port == to_compare.db_port)
00053       && (db_instance == to_compare.db_instance)
00054       && (database == to_compare.database);
00055 }
00056 
00057 void database_login_info::reset()
00058 {
00059   user_name = istring::empty_string();
00060   password = istring::empty_string();
00061   db_host = istring::empty_string();
00062   db_port = 0;
00063   db_instance = istring::empty_string();
00064   database = istring::empty_string();
00065   table_name = istring::empty_string();
00066 }
00067 
00068 bool database_login_info::read_info(ini_configurator &ini)
00069 {
00070   reset();  // clear before reading anything.
00071 
00072   const istring login_section = "database";
00073   const istring bogus = "b0gus";
00074 
00075   user_name = ini.load(login_section, "user", bogus);
00076   password = ini.load(login_section, "passwd", bogus);
00077   db_host = ini.load(login_section, "host", bogus);
00078   db_port = ini.load(login_section, "port", 0);
00079   db_instance = ini.load(login_section, "instance", bogus);
00080   database = ini.load(login_section, "database", bogus);
00081   table_name = ini.load(login_section, "table", bogus);
00082 
00083   // table is optional.
00084   if ( (user_name == bogus)
00085       || (password == bogus)
00086       || (db_host == bogus)
00087       || ( (db_instance == bogus) && (db_port == 0) )
00088       || (database == bogus) ) {
00089     reset();
00090     return false;
00091   }
00092 
00093   // reset optional or alternate parameters rather than leaving set to
00094   // sentinel values.
00095   if (table_name == bogus) table_name = "";
00096   if (db_instance == bogus) db_instance = "";
00097 
00098   return true;
00099 }
00100 
00102 
00103 #define CHECK_INDY(indy, what) \
00104   if (indy < 0) { \
00105     LOG(istring("ERROR: failed to find ") + what); \
00106     return false; \
00107   }
00108 
00109 bool database_login_info::replace_value(istring &modify, const istring &tag,
00110     const istring &replacement)
00111 {
00112   FUNCDEF("replace_value");
00113 //LOG(isprintf("looking for replace value now, section=%s", db_section.s()));
00114   istring section_tag = istring("[") + db_section + "]";
00115   int sect_indy = modify.find(section_tag, 0);
00116   if (sect_indy < 0) {
00117     modify.insert(modify.length(), istring(log_base::platform_ending())
00118         + section_tag + log_base::platform_ending());
00119     // try finding it again.
00120     sect_indy = modify.find(section_tag, 0);
00121   }
00122   CHECK_INDY(sect_indy, istring(db_section) + " section in config.");
00123   int cr_indy_1 = modify.find("\n", sect_indy);
00124   CHECK_INDY(cr_indy_1, istring("carriage return in ")
00125       + db_section + " section.");
00126   // find start of next section, if it exists.
00127   int next_sect = modify.find("[", cr_indy_1);
00128   if (next_sect < 0) next_sect = modify.length() - 1;
00129   int tag_indy = modify.find(tag, sect_indy);
00130   if ( (tag_indy < 0) || (tag_indy > next_sect) ) {
00131     // in this case it's not an error, it means we need to add the tag.
00132     modify.insert(cr_indy_1 + 1, tag + " = " + replacement
00133         + log_base::platform_ending());
00134     return true;
00135   }
00136   int cr_indy_2 = modify.find("\n", tag_indy);
00137   CHECK_INDY(cr_indy_2, istring("carriage return for tag ") + tag
00138       + " entry in " + db_section + " section");
00139   modify.zap(tag_indy + tag.length(), cr_indy_2);
00140   modify.insert(tag_indy + tag.length(), istring(" = ") + replacement
00141         + log_base::platform_ending());
00142   return true;
00143 }
00144 
00145 // simple wrapper, saved due to history.
00146 bool database_login_info::read_login_info(ini_configurator &ini,
00147     database_login_info &to_fill)
00148 { return to_fill.read_info(ini); }
00149 
00150 bool database_login_info::update_freetds_configuration()
00151 {
00152   FUNCDEF("update_freetds_configuration");
00153 //hmmm: this piece would need to be done each time if we move to only
00154 //      reading configs on startup.
00155 
00156   // write the info into freetds.conf for the section.
00157   byte_filer initial(freetds_config_file(), "rb");
00158 const int MAXIMUM_FREETDS_FILE = 8192;
00159   istring current_content;
00160   int chars_read = initial.read(current_content, MAXIMUM_FREETDS_FILE);
00161   initial.close();
00162   if (!chars_read) {
00163     LOG(istring("ERROR: failed to read freetds configuration from ")
00164         + freetds_config_file());
00165     return false;
00166   }
00167 
00168   bool to_return = replace_value(current_content, "host", db_host);
00169   if (!to_return) {
00170     LOG(istring("ERROR: failed to find or add host value to ")
00171         + freetds_config_file());
00172     return false;
00173   }
00174 
00175   // instance and port are only written if they are not at their default and
00176   // unusable value.
00177   if (db_instance.t()) {
00178     to_return = replace_value(current_content, "instance", db_instance);
00179     if (!to_return) {
00180       LOG(istring("ERROR: failed to find or add instance value to ")
00181           + freetds_config_file());
00182       return false;
00183     }
00184   }
00185   if (db_port != 0) {
00186     to_return = replace_value(current_content, "port", isprintf("%d", db_port));
00187     if (!to_return) {
00188       LOG(istring("ERROR: failed to find or add port value to ")
00189           + freetds_config_file());
00190       return false;
00191     }
00192   }
00193 
00194   byte_filer new_version(freetds_config_file(), "wb");
00195   int chars_written = new_version.write(current_content);
00196   new_version.close();
00197   if (chars_written < current_content.length()) {
00198     LOG(istring("ERROR: failed to write new version of ") + freetds_config_file());
00199     return false;
00200   }
00201 
00202   fflush(0);  // flush all changes out.
00203 
00204   return to_return;
00205 }
00206 

Generated on Fri Nov 28 04:29:14 2008 for HOOPLE Libraries by  doxygen 1.5.1