#include #include #include #include #include #include #include "sms.h" #include "config.h" #include "debug.h" #include "mr_pcre/mr_pcre.h" #include using namespace std; using namespace pcrepp; Config::Config() { // domsylne zmienne z pliku koniguracyjnego params["mailaddr"] = EmailAddress(); params["template"] = "${message}"; ReadFile(string(SMS_SYSCONFDIR) + "/" + SMS_CONFIG); ReadEnv(); ReadConfigFiles(); } void Config::ReadEnv() { char *c; if ((c = getenv("http_proxy")) || (c = getenv("HTTP_PROXY"))) { params["http_proxy"] = c; } if ((c = getenv("SMS_MAILADDR"))) params["mailaddr"] = c; } void Config::ReRead(const std::string &name) { params.clear(); ReadFile(name); } string Config::ParseConfigLine(const string &line) { string parsed, ret = line; Pcre pcre; // zastepujemy kazde wystapienie ${...} w ciagu pcre = "\\${(.*?)}"; while (1) { if (!pcre.search(ret)) break; // ciag w {} moze byc zmienna z pliku konfiguracyjnego, // badz zmienna srodowiska parsed = params[pcre.get_match(0)]; if (parsed == "") { char *c = getenv(pcre.get_match(0).c_str()); parsed = (c) ? c : ""; } ret = ret.substr(0, pcre.get_match_start(0)-2) + parsed + ret.substr(pcre.get_match_end(0)+2); } // zastepujemy kazde wystapienie `...` w ciagu pcre = "`(.*?)`"; while (1) { if (!pcre.search(ret)) break; FILE *pw; int c; parsed = ""; if ((pw = popen(pcre.get_match(0).c_str(), "r"))) { while ((c = fgetc(pw)) != EOF) parsed += (char)c; pclose(pw); } // usuwamy ostatni znak konca linii z otrzymanego stringu if (parsed[parsed.length() -1 ] == '\n') parsed = parsed.substr(0, parsed.length()-1); ret = ret.substr(0, pcre.get_match_start(0)-1) + parsed + ret.substr(pcre.get_match_end(0)+2); } return ret; } void Config::ReParse() { for(Params::iterator it = params.begin(); it != params.end(); it++) it->second = ParseConfigLine(it->second); } void Config::AddLine(const std::string &line) { size_t pos; // pomijamy komentarze if (line[0] == '#' || !line.length()) return; if ((pos = line.find('=')) > 0 ) { string p_name = line.substr(0, pos); string p_val = line.substr(pos + 1); params[p_name] = p_val; } } void Config::ReadFile(const string &filename) { const int BUFSIZE = 1024; char buffer[BUFSIZE]; ifstream file(filename.c_str()); while (file.good() && !file.eof()) { file.getline(buffer, BUFSIZE); AddLine(buffer); } } void Config::ReadConfigFiles() { string file; struct passwd *pwd; char *path; // oraz konfigi lokalne dla danego uzytkownika if ((pwd = getpwuid(geteuid()))) { if ((path = getenv("CONFIG_DIR")) && *path) ReadFile(string(pwd->pw_dir) + "/" + path + "/" + SMS_CONFIG); else ReadFile(string(pwd->pw_dir) + "/." + SMS_CONFIG); } } string Config::EmailAddress() { struct hostent *host; struct passwd *pw; char hostname[MAXHOSTNAMELEN]; string email; if ((pw = getpwuid(getuid())) && !gethostname(hostname, sizeof(hostname)-1)) { host = gethostbyname(hostname); if (host) email = string(pw->pw_name) + "@" + host->h_name; } return email; } ostream &operator<<(ostream &os, Config &c) { for(Config::Params::iterator it = c.params.begin(); it != c.params.end(); it++) os << it->first << " => " << it->second << endl; return os; } bool Config::isTrue(const std::string &s) { string &val = params[s]; return val == "on" || val == "yes" || val == "true" || val == "1"; }