00001 #ifndef APPLICATION_CONFIG_IMPLEMENTATION_FILE
00002 #define APPLICATION_CONFIG_IMPLEMENTATION_FILE
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "application_config.h"
00019
00020 #include <basis/auto_synch.h>
00021 #include <basis/istring.h>
00022 #include <basis/log_base.h>
00023 #include <basis/mutex.h>
00024 #include <basis/set.cpp>
00025 #include <data_struct/section_manager.h>
00026 #include <data_struct/string_table.h>
00027 #include <opsystem/ini_config.h>
00028 #include <textual/parser_bits.h>
00029 #include <textual/tokenizer.h>
00030
00031
00032
00033
00034 #undef LOG
00035 #define LOG(to_print) program_wide_logger().log(to_print)
00036
00038
00039 const char *PRODUCT_HEADING() { return "product"; }
00040
00041
00042 const char *ASSIGN_TOKEN() { return "="; }
00043
00044
00045 const char *SEPARATOR_TOKEN() { return ","; }
00046
00047
00048 const char *SEPARATOR_TEXT() { return ", "; }
00049
00050
00051 const char *PARMS_HEADING() { return "parms"; }
00052
00053
00054 const char *ONESHOT_HEADING() { return "oneshot"; }
00055
00056
00058
00059 application_config::application_config(const istring &config_file,
00060 const istring &basename)
00061 : _lock(new mutex),
00062 _config(new ini_configurator(config_file, ini_configurator::RETURN_ONLY,
00063 ini_configurator::APPLICATION_DIRECTORY)),
00064 _sector(new section_manager(*_config, istring(basename) + "_TOC",
00065 istring(PRODUCT_HEADING()) + "_"))
00066 {
00067 FUNCDEF("constructor");
00068 string_table startup_info;
00069 if (!find_section(STARTUP_SECTION(), startup_info)) {
00070
00071 LOG("the startup section doesn't exist yet; adding it now.");
00072 istring entry = make_startup_entry(basename, "", false);
00073 startup_info.add(STARTUP_APP_NAME(), entry);
00074 add_section(STARTUP_SECTION(), startup_info);
00075 }
00076 }
00077
00078 application_config::~application_config()
00079 {
00080 WHACK(_sector);
00081 WHACK(_config);
00082 WHACK(_lock);
00083 }
00084
00085 const char *application_config::STARTUP_SECTION()
00086 { return "PRIVATE_STARTUP_LNCH1.0"; }
00087
00088 const char *application_config::STARTUP_APP_NAME()
00089 { return "placeholder"; }
00090
00091 bool application_config::product_exists(const istring &product)
00092 {
00093 auto_synchronizer l(*_lock);
00094 if (!_sector->section_exists(product)) return false;
00095 return true;
00096 }
00097
00098 istring application_config::find_program(const istring &product,
00099 const istring &app_name, int &level)
00100 {
00101 auto_synchronizer l(*_lock);
00102 istring heading = _sector->make_section_heading(product);
00103 istring found = _sector->config().load(heading, app_name, "");
00105
00106
00107 if (!found) {
00108
00109
00110
00111
00112 if (product.iequals("supervisor")) {
00113
00114 heading = _sector->make_section_heading("core");
00115 found = _sector->config().load(heading, app_name, "");
00116 } else if (product.iequals("lightlink")) {
00117 heading = _sector->make_section_heading("core");
00118 found = _sector->config().load(heading, app_name, "");
00119 if (!found) {
00120
00121 heading = _sector->make_section_heading("server");
00122 found = _sector->config().load(heading, app_name, "");
00123 }
00124 }
00125 }
00126
00128 found = parser_bits::substitute_env_vars(found);
00129
00130 int comma_loc = found.find(",");
00131 if (negative(comma_loc)) return "";
00132 level = found.convert(0);
00133 found.zap(0, comma_loc);
00134
00135 return found;
00136 }
00137
00138 bool application_config::add_program(const istring &product,
00139 const istring &app_name, const istring &full_path, int level)
00140 {
00141 FUNCDEF("add_program");
00142 auto_synchronizer l(*_lock);
00143 bool existed = true;
00144
00145 string_table info_table;
00146 if (!_sector->section_exists(product)) {
00147 existed = false;
00148 } else
00149 find_section(product, info_table);
00150 #ifdef DEBUG_APP_CONFIG
00151 if (existed) {
00152 LOG(istring("section for ") + product + " found:");
00153 for (int i = 0; i < info_table.symbols(); i++)
00154 LOG(istring("key=") + info_table.name(i) + " value=" + info_table[i]);
00155 } else LOG(istring("section for ") + product + " not found.");
00156 #endif
00157
00158 info_table.whack(app_name);
00159
00160 isprintf full_entry("%d,%s", level, full_path.s());
00161 info_table.add(app_name, full_entry);
00162 #ifdef DEBUG_APP_CONFIG
00163 LOG(istring("new section for ") + product + " has:");
00164 for (int i = 0; i < info_table.symbols(); i++)
00165 LOG(istring("key=") + info_table.name(i) + " value=" + info_table[i]);
00166 #endif
00167
00168
00169 if (existed) return replace_section(product, info_table);
00170 else return add_section(product, info_table);
00171 }
00172
00173 bool application_config::remove_program(const istring &product,
00174 const istring &app_name)
00175 {
00176 FUNCDEF("remove_program");
00177 auto_synchronizer l(*_lock);
00178
00179 string_table info_table;
00180 if (!find_section(product, info_table)) return true;
00181
00182 info_table.whack(app_name);
00183
00184
00185 return replace_section(product, info_table);
00186 }
00187
00188 bool application_config::find_section(const istring §ion_name,
00189 string_table &info_found)
00190 {
00191 FUNCDEF("find_section");
00192 info_found.reset();
00193 auto_synchronizer l(*_lock);
00194 if (!_sector->find_section(section_name, info_found)) {
00195 LOG(section_name + " was not found in the configuration.");
00196 return false;
00197 }
00198 return true;
00199 }
00200
00201 bool application_config::add_section(const istring §ion_name,
00202 const string_table &info_found)
00203 {
00204 auto_synchronizer l(*_lock);
00205 return _sector->add_section(section_name, info_found);
00206 }
00207
00208 bool application_config::replace_section(const istring §ion_name,
00209 const string_table &info_found)
00210 {
00211 auto_synchronizer l(*_lock);
00212 return _sector->replace_section(section_name, info_found);
00213 }
00214
00215 istring application_config::make_startup_entry(const istring &product,
00216 const istring &parms, bool one_shot)
00217 {
00218 return istring(PRODUCT_HEADING()) + ASSIGN_TOKEN() + product
00219 + SEPARATOR_TEXT() + PARMS_HEADING() + ASSIGN_TOKEN()
00220 + parms + SEPARATOR_TEXT() + ONESHOT_HEADING() + ASSIGN_TOKEN()
00221 + istring(istring::SPRINTF, "%d", one_shot);
00222 }
00223
00224 bool application_config::parse_startup_entry(const istring &info,
00225 istring &product, istring &parms, bool &one_shot)
00226 {
00227 FUNCDEF("parse_startup_section");
00228
00229 tokenizer entry_parser(SEPARATOR_TOKEN(), ASSIGN_TOKEN());
00230 entry_parser.parse(info);
00231
00232 product = entry_parser.find(PRODUCT_HEADING());
00233 parms = entry_parser.find(PARMS_HEADING());
00234
00235 istring once = entry_parser.find(ONESHOT_HEADING());
00236 one_shot = (bool)once.convert(0);
00237
00238 if (!product) return false;
00239 return true;
00240 }
00241
00242 bool application_config::find_entry(const string_table &table,
00243 const istring &name, istring &location)
00244 {
00245
00246 istring *found = table.find(name);
00247 if (!found) return false;
00248
00249 location = *found;
00250 return true;
00251 }
00252
00253 bool application_config::add_startup_entry(const istring &product,
00254 const istring &app_name, const istring ¶meters, int one_shot)
00255 {
00256 FUNCDEF("add_startup_entry");
00257 auto_synchronizer l(*_lock);
00258
00259 LOG(istring("product \"") + product + "\", application \"" + app_name
00260 + (one_shot? istring("\", OneShot") : istring("\", MultiUse")));
00261
00262 string_table startup_info;
00263 if (!find_section(STARTUP_SECTION(), startup_info)) {
00264
00265
00266 LOG("internal startup section not found!");
00267 return false;
00268 }
00269
00270 istring new_entry = make_startup_entry(product, parameters,
00271 one_shot);
00272 startup_info.add(app_name, new_entry);
00273 if (!replace_section(STARTUP_SECTION(), startup_info))
00274 return false;
00275
00276
00277 return true;
00278 }
00279
00280 bool application_config::remove_startup_entry(const istring &product,
00281 const istring &app_name)
00282 {
00283 FUNCDEF("remove_startup_entry");
00284 auto_synchronizer l(*_lock);
00285
00286 LOG(istring("product \"") + product + "\", application \"" + app_name + "\"");
00287
00288 string_table startup_info;
00289 if (!find_section(STARTUP_SECTION(), startup_info)) {
00290
00291 add_section(STARTUP_SECTION(), startup_info);
00292
00293 if (!find_section(STARTUP_SECTION(), startup_info)) {
00295
00296
00297 return false;
00298 }
00299 }
00300
00301
00302 istring entry_found;
00303 if (!find_entry(startup_info, app_name, entry_found)) {
00304
00305 LOG(istring("no entry was found for ") + app_name);
00306 return false;
00307 }
00308
00309 startup_info.whack(app_name);
00310 if (!replace_section(STARTUP_SECTION(), startup_info)) {
00311
00312 return false;
00313 }
00314
00315 return true;
00316 }
00317
00318
00319 #endif //APPLICATION_CONFIG_IMPLEMENTATION_FILE
00320