#include #include #include #if (__GNUC__ >= 3) #include #else #include typedef std::strstream stringstream; #endif #include "mr_curl/mr_curl.h" #include "generic_sms.h" #include "app.h" #include "debug.h" #include "sms.h" using namespace std; App::App(int argc, char **argv) { ParseCommandLine(argc, argv); OpenAddrBook(); } void App::ShowHelp() { cerr << "Usage:\n\n\tsms \n"; cerr << "\tsms -g era -n 602000000 -m \"sms body\"\n"; cerr << "\tdate | sms -s -g era -o phone_no=602000000 -m -\n\n"; cerr << "-g gateway : era, eranet, miastoplusa, orangembox, plusmail, plus, o2uk\n"; cerr << "-n no : phone number to sent SMS to\n"; cerr << "-m msg : message to sent, '-' means stdin\n"; cerr << "-c config : use specified config file instead of default ones\n"; cerr << "-o option : option with assigned value exactly like in .smsrc file\n"; cerr << "-t sig : signature to add to the message\n"; cerr << "-p num : max no of messages to sent\n"; cerr << "-h : show this help screen\n"; cerr << "-v : verbose\n"; cerr << "-s : show additional sms gateway information (if available)\n"; cerr << "-r : delivery notification (if available)\n"; cerr << "-V : show version information\n"; cerr << "-C : check whether newer version is available\n"; cerr << "sms " << SMS_VERSION << ", use at your own risk!" << endl; } int App::CheckNewVersion() { Curl curl; CURLcode ret = curl.PerformGet(SMS_NEWVERURL); if (!ret) { string ver = curl.Body(); ver = ver.substr(0, ver.length()-1); return ver != SMS_VERSION ? 1 : 0; } return -1; } void App::ParseCommandLine(int argc, char **argv) { int ch; while ((ch = getopt(argc, argv, "CVrc:svhg:n:m:o:t:p:")) != -1) { switch (ch) { // czy jest nowa wersja? case 'C': switch (CheckNewVersion()) { case 0: cout << "No new version available." << endl; exit(0); break; case 1: cout << "New version available." << endl; exit(1); break; default: cerr << "Cannot check new version." << endl; exit(-1); } break; // wersja programu case 'V': cout << "sms " << SMS_VERSION << endl; exit(0); break; // wybor rodzaju bramki case 'g': config["gateway"] = optarg; break; // numer telefonu case 'n': config["phone_no"] = optarg; break; // wiadomosc do wyslania case 'm': { string msg = optarg; if (msg == "-") { stringstream str; cin >> str.rdbuf(); msg = str.str(); } config["message"] = msg; } break; // status doreczenia case 'r': config["notify"] = "1"; break; // inny plik konfiguracyjny case 'c': config.ReRead(optarg); break; // opcja z pliku konfiguracyjnego case 'o': config.AddLine(optarg); break; // inne info pobierane z bramki case 's': config["stats"] = "1"; break; // na ile SMSow mozna podzielic tresc case 'p': config["num_parts"] = optarg; break; // podpis case 't': config["signature"] = optarg; break; // verbose case 'v': config["verbose"] = "1"; break; // domyslnie pokazujemy helpa case 'h': default: ShowHelp(); exit(1); } } argc -= optind; argv -= optind; } void App::OpenAddrBook() { string file; struct passwd *pwd; char *path; if ((pwd = getpwuid(geteuid()))) { if ((path = getenv("CONFIG_DIR")) && *path) file = string(pwd->pw_dir) + "/" + path + "/" + SMS_ADDRBOOK; else file = string(pwd->pw_dir) + "/." + SMS_ADDRBOOK; addr.Open(file, 0, GDBM_READER); } } string App::LookupAddrBook(string &str) { try { Cdatum key(str), ret; ret = addr[key]; return ret; } catch (...) { } return ""; } int App::Run() { int status = 0; string s; s = LookupAddrBook(config["phone_no"]); if (s != "") config["phone_no"] = s; config.ReParse(); if (config.isTrue("verbose")) cout << config << endl; if (GenericSMS *sms = &GenericSMS::Factory(config)) { if (config["phone_no"] !="" && config["template"] != "") { if (!sms->SendMessage(config["phone_no"], config["template"])) status = 1; } if (config.isTrue("stats")) sms->ShowStats(); delete sms; } return status; }