00001
00002
00003
00004
00005
00006 extern "C" {
00007 #include <sys/stat.h>
00008 #include <sys/types.h>
00009 }
00010
00011 #include <fstream>
00012 #include <iostream>
00013 #include <sstream>
00014
00015 #include "loader.h"
00016 #include "util.h"
00017
00018 Loader::Loader() {
00019 }
00020
00021 Loader::~Loader() {
00022 }
00023
00024 bool Loader::load(MSettings *settings, string path,
00025 bool suppressWarning, bool caseSensitive)
00026 {
00027
00028 ifstream is(path.c_str());
00029
00030 if (!is) {
00031 if (!suppressWarning) {
00032 cerr << "ncwm[W " << Util::timestamp()
00033 << "]: cannot open/read configuration file '"
00034 << path << "', skipping" << endl;
00035 }
00036 return false;
00037 }
00038
00039 string key = "";
00040 string value = "";
00041 string buf = "";
00042 bool comment = false;
00043 bool ignoreWhitespaces = true;
00044 bool escape = false;
00045 int c;
00046
00047 while (!is.eof()) {
00048
00049 c = is.get();
00050
00051 switch (c) {
00052 case ' ':
00053 case '\t':
00054 if (!comment && !ignoreWhitespaces) {
00055 buf += c;
00056 }
00057 escape = false;
00058 break;
00059 case '"':
00060 if (!comment) {
00061 if (escape) {
00062 buf += c;
00063 }
00064 else {
00065 ignoreWhitespaces = !ignoreWhitespaces;
00066 }
00067 }
00068 escape = false;
00069 break;
00070 case '\\':
00071 if (!comment) {
00072 if (escape) {
00073 buf += c;
00074 escape = false;
00075 }
00076 else {
00077 escape = true;
00078 }
00079 }
00080 break;
00081 case '#':
00082 if (escape) {
00083 buf += c;
00084 }
00085 else {
00086 comment = true;
00087 }
00088 escape = false;
00089 break;
00090 case '=':
00091 if (!comment) {
00092 if (escape) {
00093 buf += c;
00094 }
00095 else {
00096 key = buf;
00097 buf = "";
00098 }
00099 }
00100 escape = false;
00101 break;
00102 case '\n':
00103
00104 #define ENDLINE \
00105 if (!escape) { \
00106 comment = false; \
00107 ignoreWhitespaces = true; \
00108 value = buf; \
00109 if ((key != "") && (value != "")) { \
00110 value = buf; \
00111 if (caseSensitive) { \
00112 (*settings)[key] = value; \
00113 } \
00114 else { \
00115 (*settings)[Util::lowerCase(key)] = value; \
00116 } \
00117 } \
00118 buf = key = value = ""; \
00119 } \
00120 escape = false; \
00121 break; \
00122
00123 ENDLINE
00124 case EOF :
00125 ENDLINE
00126 default:
00127 if (!comment) {
00128 buf += c;
00129 }
00130 escape = false;
00131 break;
00132 }
00133 }
00134 is.close();
00135
00136 return true;
00137 }
00138
00139 bool Loader::saveSettings(MSettings *settings, string path) {
00140
00141 ostringstream content;
00142
00143 for (MSettings::iterator it = settings->begin();
00144 it != settings->end(); it++)
00145 {
00146 string value = Util::encodeEscapes((*it).second);
00147 if (Util::containsWhitespaces(value)) {
00148 content << (*it).first << "=\"" << value << "\"" << endl;
00149 }
00150 else {
00151 content << (*it).first << "=" << value << endl;
00152 }
00153 }
00154
00155 return saveFile(path, content.str());
00156 }
00157
00158 bool Loader::saveFile(string path, string content) {
00159
00160 string dir = Util::canonicalDir(path);
00161 if (!Util::exists(dir.c_str())) {
00162
00163 mode_t mode = umask(0);
00164 mode = (mode ^ (S_IRWXU | S_IRWXG | S_IRWXO)) | S_IWUSR | S_IXUSR;
00165 if (mkdir(dir.c_str(), mode) != 0) {
00166 cerr << "ncwm[W " << Util::timestamp()
00167 << "]: cannot create non-existing directory '"
00168 << dir << "', skipping" << endl;
00169 }
00170 }
00171
00172 ofstream os(path.c_str());
00173
00174 if (!os) {
00175 cerr << "ncwm[W " << Util::timestamp()
00176 << "]: cannot open/write configuration file '"
00177 << path << "', skipping" << endl;
00178 return false;
00179 }
00180
00181 os << content;
00182 os.close();
00183
00184 return true;
00185
00186 }
00187
00188 void Loader::print(MSettings *settings) {
00189
00190 MSettings::iterator it = settings->begin();
00191 while (it != settings->end()) {
00192 cout << (*it).first << "=" << (*it).second << endl;
00193 it++;
00194 }
00195 }