#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define NO_MFC #include #include "ba7.h" #include "ba7100a.h" #define NOT_TRANS -883 #define NOT_GEST -884 /////////////////////////////////////////////////////////// // TConfig utilities /////////////////////////////////////////////////////////// TString& set_ini_var(int cfg, const char* para, const char* var, const char* val) { static TString80 prev; TConfig ini(cfg, para); prev = ini.get(var); if (val != NULL) ini.set(var, val); return prev; } inline TString& get_ini_var(int cfg, const char* para, const char* var) { return set_ini_var(cfg, para, var, NULL); } /////////////////////////////////////////////////////////// // TMail_box /////////////////////////////////////////////////////////// class TMail_box : public TSocketClient { unsigned long _connection; public: bool default_params(TString& server, TString& user,TString& password); bool logon(const char* server = NULL, const char* usr = NULL, const char* pwd = NULL); virtual bool ok() const { return _connection != NULL; } bool list(TString_array& a); int get(TMail_messages& m); bool remove(const char* id); void logoff(); TMail_box(); ~TMail_box(); }; bool TMail_box::default_params(TString& server, TString& user,TString& password) { bool ok = TRUE; if (server.empty()) { server = get_ini_var(CONFIG_INSTALL, "Server", "POP3"); if (server.empty()) ok = FALSE; } if (user.empty()) user = ::user(); if (password.empty()) { const TString& pwd = cache().get(LF_USER, user).get("PASSWORD"); password = ::decode(pwd); } return ok; } bool TMail_box::logon(const char* ser, const char* usr, const char* pwd) { if (_connection) logoff(); if (!IsOk()) return error_box("Impossibile inizializzare il client POP3"); TString server(ser); TString user(usr); TString password(pwd); if (!default_params(server, user, password)) return error_box("E' necessario specificare un server POP3, un utente ed una password"); _connection = QueryConnection("110", server); if (_connection != 0) { TString buf; TString req; ReadLine(_connection, buf); if (buf[0] != '+') return error_box("Il server POP3 %s non risponde\nRisultato : %s", (const char*)server, (const char *)buf); buf = "USER "; buf << user << "\r\n"; WriteLine(_connection, buf); req = buf; ReadLine(_connection, buf); if (buf[0] != '+') return error_box("Il server POP3 %s non accetta l'utente %s\nRichiesta : %sRisultato : %s", (const char*)server, (const char*)user, (const char *) req, (const char *)buf); buf = "PASS "; buf << password << "\r\n"; WriteLine(_connection, buf); req = buf; ReadLine(_connection, buf); if (buf[0] != '+') return error_box("Il server POP3 %s non accetta la password dell'utente %s\nRichiesta : %sRisultato : %s", (const char*)server, (const char*)user, (const char *) req, (const char *)buf); } else return error_box("Impossibile contattare il server POP3 %s", (const char*)server); return TRUE; } void TMail_box::logoff() { if (_connection) { WriteLine(_connection, "QUIT\r\n"); RemoveConnection(_connection); _connection = NULL; } } bool TMail_box::list(TString_array& a) { bool ok = _connection != NULL; if (ok) { TString buf; buf = "LIST\r\n"; WriteLine(_connection, buf); ReadLine(_connection, buf); ok = buf[0] == '+'; while (ok) { if (!ReadLine(_connection, buf)) break; // Unexpected EOF if (buf[0] == '.') break; int pos = buf.find(' '); if (pos > 0) buf.cut(pos); a.add(buf); } } return ok; } HIDDEN int str2month(const char* str) { const char* const mese[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; int m; for (m = 11; m > 0; m--) { if (stricmp(str, mese[m]) == 0) break; } return m+1; } enum EncodingType { enc_plain_text, enc_quoted_printable, enc_base64 }; int TMail_box::get(TMail_messages& m) { // Lista dei caratteri validi const char Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+*"; // Lista per decodifica dei caratteri validi char Deco64[256]; memset(Deco64, ' ', sizeof(Deco64)); for (int i = 0; Base64[i]; i++) Deco64[Base64[i]] = i; TString_array a; list(a); TString buf, boundary, msg_line; m.destroy(); FOR_EACH_ARRAY_ROW(a, r, row) { TMail_message* msgptr = new TMail_message(user()); m.add(msgptr); TMail_message& msg = *msgptr; buf = "RETR "; buf << *row << "\r\n"; WriteLine(_connection, buf); ReadLine(_connection, buf); bool ok = buf[0] == '+'; EncodingType encoding = enc_plain_text; bool in_body = FALSE; bool in_section = FALSE; bool buf_already_read = FALSE; boundary.cut(0); while (ok) { if (!buf_already_read) { if (!ReadLine(_connection, buf)) { ok = FALSE; break; // Unexpected EOF } } else buf_already_read = FALSE; if (buf[0] == '.') { buf.ltrim(1); if (buf.blank()) break; } if (in_body) { if (buf[0] == '-' && boundary.not_empty() && buf.find(boundary) >= 0) break; // Ignora sezioni di attachment switch (encoding) { case enc_base64: { unsigned val = 0; int bits = 0; msg_line.cut(0); for (const char* s = buf; *s && *s != '='; s++) { if (*s==0x0A || *s==0x0D || *s==0x20 || *s==0x09) continue; // Salta eventuali blanks val <<= 6; val |= Deco64[*s]; bits += 6; if (bits >= 8) { const char c = char((val >> (bits - 8)) & 0xFF); msg_line << c; bits -= 8; } } msg.add_line(msg_line); } break; case enc_quoted_printable: { msg_line.cut(0); for (const char* s = buf; *s; s++) { if (*s == '=') { s++; if (*s >= ' ') { int c; sscanf(s, "%2X", &c); msg_line << char(c); s++; } } else msg_line << *s; } msg.add_line(msg_line); } break; default: buf.rtrim(); msg.add_line(buf); break; } } else { if (boundary.not_empty()) { if (buf.blank()) { in_body = in_section; } else { if (buf.find(boundary) >= 0) in_section = TRUE; } } else { if (buf.blank()) { in_body = TRUE; continue; } } if (buf.compare("From:", 5, TRUE) == 0) { buf.ltrim(6); buf.trim(); msg.set_sender(buf); continue; } if (buf.compare("To:", 3, TRUE) == 0) { buf.ltrim(4); buf.trim(); msg.add_recipient(buf); continue; } if (buf.compare("Cc:", 3, TRUE) == 0) { buf.ltrim(4); buf.trim(); msg.add_copy_recipient(buf); continue; } if (buf.compare("Subject:", 8, TRUE) == 0) { buf.ltrim(9); buf.trim(); msg.set_subject(buf); continue; } if (buf.compare("Date:", 5, TRUE) == 0) { TToken_string d(buf.mid(6), ' '); d.trim(); int giorno = d.get_int(1); int mese = str2month(d.get()); int anno = d.get_int(); if (anno < 1000) anno += anno >= 98 ? 1900 : 2000; TString16 ora = d.get(); buf.cut(0); buf << anno << '/' << mese << '/' << giorno << ' ' << ora; msg.set_date_time(buf); continue; } if (buf.compare("Content-Transfer-Encoding:", 26, TRUE) == 0) { if (buf.find("base64") > 0) encoding = enc_base64; else if (buf.find("quoted-printable") > 0) encoding = enc_quoted_printable; continue; } if (buf.compare("Content-Type:", 13, TRUE) == 0) { int bnd = buf.find("oundary="); // Funziona per Boundary e boundary if (bnd < 0) { ReadLine(_connection, buf); bnd = buf.find("oundary="); if (bnd < 0) buf_already_read = TRUE; } if (bnd > 0) { const int apicia = buf.find('"', bnd); const int apicic = buf.find('"', apicia+1); if (apicia > 0 && apicic > apicia) boundary = buf.sub(apicia+1, apicic); } continue; } } } } return m.items(); } bool TMail_box::remove(const char* id) { bool ok = _connection != NULL; if (ok) { TString buf; buf << "DELE " << id << "\r\n"; WriteLine(_connection, buf); ReadLine(_connection, buf); ok = buf[0] == '+'; } return ok; } TMail_box::TMail_box() : _connection(NULL) { } TMail_box::~TMail_box() { logoff(); } /////////////////////////////////////////////////////////// // TFilter_expr /////////////////////////////////////////////////////////// class TFilter_expr : public TExpression { TAutomask& _mask; protected: virtual bool print_error(const char* msg) const; public: TFilter_expr(TAutomask& m, int logicnum, const char* expr); virtual ~TFilter_expr() { } }; bool TFilter_expr::print_error(const char* msg) const { return _mask.error_box(msg); } TFilter_expr::TFilter_expr(TAutomask& m, int logicnum, const char* expr) : _mask(m) { bool ok = set(expr, _strexpr); if (ok) { if (logicnum < LF_USER || logicnum >= prefix().items()) logicnum = LF_TABCOM; // Niente errori fatali, se possibile TLocalisamfile isf(logicnum); TRectype& rec = isf.curr(); for (int i = 0; i < numvar(); i++) if (!rec.exist(varname(i))) { _error = 883; TString msg; msg << "Il campo " << varname(i) << " non appartiene al file " << logicnum; print_error(msg); break; } } } /////////////////////////////////////////////////////////// // TMailer_mask /////////////////////////////////////////////////////////// class TMailer_mask : public TAutomask { long _timer_id; long _secs; int _mail_semaphore; TMail_messages _box; bool _sequential; TString_array _key1; // Elenco dei campi della chiave principale dei files TAssoc_array _apps; // Elenco delle applicazioni per processare i files protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); virtual void handler(WINDOW win, EVENT* ep); protected: bool file2app(const TString& file, TString& app) const; void expand_tabs(TMail_message& str, const int tab = 8) const; void save_sheet(TConfig& ini, short dlg, const char* var) const; void load_sheet(TConfig& ini, short dlg, const char* var); TToken_string& get_key1(int lf) const; bool build_key1(int lf, const TString& body, TToken_string& key) const; void find_redundant_messages(); public: void test_delete(); int fill_messages(); bool exec_app(int & err, const char * appname, TMail_message & msg); bool save_sheet_line(int& err, int line = -1); void save_all_lines(); void auto_save_all(); void save() const; void load(); TMailer_mask(); virtual ~TMailer_mask(); }; void TMailer_mask::test_delete() { TWait_cursor hourglass; xvt_statbar_set("Eliminazione messaggi POP3..."); do_events(); TSheet_field& sf = sfield(F_MESSAGES); TString16 mailer, id; TMail_messages mapidel; // Lista dei messaggi MAPI da cancellare TMail_box mailbox; FOR_EACH_SHEET_ROW_BACK(sf, nrow, row) if (*row->get(0) == 'X') { row->get(sf.cid2index(F_MAILER), mailer); row->get(sf.cid2index(F_ID), id); if (mailer == "POP3") { if (!mailbox.ok()) { if (!mailbox.logon(get(F_SERVER), get(F_USER), get(F_PASSWORD))) break; } if (!mailbox.remove(id)) error_box("Impossibile cancellare il messaggio POP3 %s", (const char*)id); } else { TMail_message* msg = new TMail_message(""); msg->set_id(id); mapidel.add(msg); } sf.destroy(nrow); } mailbox.logoff(); if (mapidel.items() > 0) { xvt_statbar_set("Eliminazione messaggi MAPI..."); do_events(); mapidel.remove(); } xvt_statbar_set("Pronto"); do_events(); } void TMailer_mask::expand_tabs(TMail_message& msg, const int tab) const { const int items = msg.items(); for (int n = 0; n < items; n++) { TString & str = msg.row(n); int start = 0; for (int i = 0; str[i]; i++) { switch(str[i]) { case '\n': case '\r': start = i+1; break; case '\t': { const int t = tab - ((i-start) % tab) - 1; str[i] = ' '; if (t > 0) { TString80 spac; spac.spaces(t); str.insert(spac, i+1); i += t; } } break; default: break; } } } } int TMailer_mask::fill_messages() { TWait_cursor hourglass; TString server(get(F_SERVER)); TString user(get(F_USER)); TString password(get(F_PASSWORD)); TMail_box mailbox; if (mailbox.default_params(server, user, password)) { set(F_SERVER, server); set(F_USER, user); set(F_PASSWORD, password); } int totmapi = 0; if (get_bool(F_MAPI)) { xvt_statbar_set("Ricezione messaggi MAPI..."); do_events(); totmapi = _box.get(); } xvt_statbar_set("Ricezione messaggi POP3..."); do_events(); mailbox.logon(server, user, password); mailbox.get(_box); mailbox.logoff(); TSheet_field& sf = sfield(F_MESSAGES); sf.destroy(); TString mess; for (int m = 0; m < _box.items(); m++) { TMail_message& msg = _box.msg(m); TToken_string& row = sf.row(m); row.add(msg.sender(), sf.cid2index(F_SENDER)); row.add(msg.date(), sf.cid2index(F_DATE)); const real t = msg.time(); row.add(t.string("@@:@@:@@"), sf.cid2index(F_TIME)); row.add(msg.subject(), sf.cid2index(F_SUBJECT)); expand_tabs(msg); mess.cut(0); FOR_EACH_ARRAY_ROW(msg, i, msgrow) { mess << *msgrow; if (mess.len() >= 1024) break; } row.add(mess, sf.cid2index(F_BODY)); row.add(m= LF_USER && filenum < prefix().items()) { TLocalisamfile isf(filenum); ok = isf.get_relapp(app); } } else { const int len = file.len(); if (len == 3 || (len == 4 && file[0] == '%')) { TTable table(file); ok = table.get_relapp(app); } } } else ok = TRUE; ((TMailer_mask*)this)->_apps.add(file, app); // Fool const } else { app = *run; ok = app.not_empty(); } return ok; } bool is_incomplete(const TString& l) { if (l[0] == '[') return FALSE; const char a = l.right(1)[0]; if (a == '=') return TRUE; const int eq = l.find("= '"); if (eq > 0 && eq < 20) return a != '\''; return FALSE; } void adjust_long_lines(const TFilename& tmp) { TFilename dst_name; dst_name.temp(); ofstream dst(dst_name); bool adjusted = FALSE; TScanner org(tmp); while (TRUE) { const TString& l = org.line(); if (l.empty()) break; if (is_incomplete(l)) { adjusted = TRUE; dst << l; org.line(); char s = l[0]; if (s == '\'' || s == '"') { char c = l.right(1)[0]; while (c != '\'' && c != '"') { dst << l; org.line(); c = l.right(1)[0]; } } else dst << '\n'; } dst << l << '\n'; } org.close(); dst.close(); if (adjusted) fcopy(dst_name, tmp); remove(dst_name); } bool TMailer_mask::exec_app(int & err, const char * appname, TMail_message & msg) { TFilename tmp; tmp.temp(); { ofstream outf(tmp); const int items = msg.items(); bool long_lines = FALSE; TString message; for (int i = 0; i < items; i++) { message = msg.row(i); message.replace('\r', '\n'); outf << message; } outf.close(); adjust_long_lines(tmp); TConfig ini(tmp, "Transaction"); ini.set("From", msg.sender()); } TString command_line(appname); command_line << " /i" << tmp; TExternal_app app(command_line); err = app.run(); xvt_sys_sleep(1000); bool ok = err == NOERR; if (ok) { TConfig ini(tmp, "Transaction"); ok = ini.get("Result") == "OK"; if (ok) err = 0; else err = ini.get_int("Error"); } ::remove(tmp); return ok; } bool TMailer_mask::save_sheet_line(int& err, int nrow) { TSheet_field& sf = sfield(F_MESSAGES); TMask& m = sf.sheet_mask(); if (nrow < 0) nrow = sf.selected(); else sf.update_mask(nrow); TToken_string& row = sf.row(nrow); const TString& msg = m.get(F_BODY); if (msg.find("[Transaction]") < 0) { err = NOT_TRANS; return FALSE; // It's not a transaction } TString subj = m.get(F_SUBJECT); if (isalpha(subj[0])) // Controlla se la tabella in realtà è comune ed aggiunge il simbolino % { TString8 para; para << '[' << LF_TABCOM << ']'; if (msg.find(para) > 0) subj.insert("%"); } TFilename appname; if (!file2app(subj, appname)) // It hasn't a valid application { err = NOT_GEST; return FALSE; } TMail_message& full_msg = _box.msg(nrow); bool ok = exec_app(err, appname, full_msg); if (!ok && err == _iskeynotfound) { TString & first_row = full_msg.row(0); int pos = first_row.find("MODIFY"); if (pos > 0) { first_row.overwrite("INSERT", pos); ok = exec_app(err, appname, full_msg); } } if (ok) { if (m.is_running()) { m.set(F_CHECKED, "X"); m.stop_run(K_AUTO_ENTER); } else { row.add("X", 0); sf.force_update(nrow); } } // Restore mail recipient // if (old_mailto.not_empty()) // set_ini_var(CONFIG_INSTALL, "Main", "MailTo", old_mailto); return ok; } TToken_string& TMailer_mask::get_key1(int lf) const { TString_array& k1 = (TString_array&)_key1; // fool const; if (k1.objptr(lf) == NULL) { TLocalisamfile file(lf); const RecDes* recd = file.curr().rec_des(); // Descrizione del record della testata const KeyDes& kd = recd->Ky[0]; // Elenco dei campi della chiave 1 TToken_string key; for (int i = 0; i < kd.NkFields; i++) { const int nf = kd.FieldSeq[i] % MaxFields; const RecFieldDes& rf = recd->Fd[nf]; key.add(rf.Name); } k1.add(key, lf); } return k1.row(lf); } bool TMailer_mask::build_key1(int lf, const TString& body, TToken_string& key) const { key.format("%d", lf); TString16 field; // Nome del campo chiave TString value; // Valore del campo chiave TToken_string& key1 = get_key1(lf); // Elenco dei campi chiave FOR_EACH_TOKEN(key1, fld) { field = fld; field.insert("\n"); const int start = body.find(field); if (start < 0) return FALSE; const int equal = body.find('=', start); if (equal < 0) return FALSE; const int stop = body.find('\n', equal); if (stop < 0) return FALSE; value = body.sub(equal+1, stop); value.trim(); if (value[0] == '"' && value.right(1) == "\"") // Toglie eventuali virgolette { value.rtrim(1); value.ltrim(1); } key.add(value); } return TRUE; } void TMailer_mask::find_redundant_messages() { // Elenco dei records (chiavi primarie) già processati (virtualmente) TAssoc_array andreotti; TSheet_field& sf = sfield(F_MESSAGES); TString subj, body; TToken_string key1; // Scorro tutti i messaggi non ancora elaborati FOR_EACH_SHEET_ROW_BACK(sf, nrow, row) if (*row->get(0) != 'X') { row->get(sf.cid2index(F_BODY), body); if (body.find("[Transaction]") < 0) // Scarto i messaggi che non siano transazioni continue; row->get(sf.cid2index(F_SUBJECT), subj); int lfile = LF_TAB; // Numero logico del file if (isalpha(subj[0])) // Controlla se la tabella in realtà è comune ed aggiunge il simbolino % { TString8 para; para << '[' << LF_TABCOM << ']'; if (body.find(para) > 0) lfile = LF_TABCOM; } else lfile = atoi(subj); if (build_key1(lfile, body, key1)) { if (andreotti.is_key(key1)) row->add("R", 0); // Messaggio ridondante! else andreotti.add(key1); // Messaggio da processare! } } } void TMailer_mask::save_all_lines() { TBrowsefile_field& bf = (TBrowsefile_field&)field(F_LOG); TViswin& vv = bf.vis_win(); TSheet_field& sf = sfield(F_MESSAGES); TString body, msg; time_t tempo; time(&tempo); const struct tm* d = localtime(&tempo); msg.format("- Inizio elaborazione: %02d-%02d-%04d %02d:%02d:%02d", d->tm_mday, d->tm_mon+1, 1900+d->tm_year, d->tm_hour, d->tm_min, d->tm_sec); vv.add_line(msg); find_redundant_messages(); bool one_saved = FALSE; FOR_EACH_SHEET_ROW(sf, nrow, row) { msg.format("Messaggio %d ", nrow+1); const char mark = *row->get(0); if (mark == 'X') msg << "ignorato in quanto già elaborato"; if (mark == 'R') { msg << "ignorato in quanto ridondante"; row->add("X", 0); // Marcalo come elaborato comunque } if (mark <= ' ') { row->get(sf.cid2index(F_BODY), body); if (body.find("[Transaction]") >= 0) { int err = 0; const bool yes = save_sheet_line(err, nrow); if (yes) { msg << "elaborato con successo"; one_saved = TRUE; } else if (err == NOT_GEST) { const TMask& m = sf.sheet_mask(); msg << " definire il programma gestore del file " << m.get(F_SUBJECT); } else { msg << "non elaborato a causa di un errore (n.ro " << err << ')'; if (_sequential) break; } } else msg << "ignorato in quanto transazione non riconosciuta"; } vv.add_line(msg); } time(&tempo); d = localtime(&tempo); msg.format("- Fine elaborazione: %02d-%02d-%04d %02d:%02d:%02d", d->tm_mday, d->tm_mon+1, 1900+d->tm_year, d->tm_hour, d->tm_min, d->tm_sec); vv.add_line(msg); vv.add_line(""); vv.goto_end(); sf.force_update(); // Fai apparire tutte le X #ifdef DBG if (one_saved && yesno_box("Si desidera eliminare i messaggi processati?")) #else if (one_saved) #endif { test_delete(); fill_messages(); } } bool TMailer_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case F_TIMER: if (e == fe_init || e == fe_modify) { if (_timer_id != XVT_TIMER_ERROR) { xvt_timer_destroy(_timer_id); _timer_id = XVT_TIMER_ERROR; } const long minutes = atol(o.get()); if (minutes > 0) { _timer_id = xvt_timer_create(win(), 1000L); _secs = 0L; if (_timer_id == XVT_TIMER_ERROR) return error_box("Impossibile impostare il timer"); } } break; case F_MESSAGES: if (e == fe_init) { if (!field(F_SERVER).empty() && !field(F_USER).empty() && !field(F_PASSWORD).empty()) { // auto_save_all(); // Un po' troppo precipitoso: non permette di intervenire all'accensione fill_messages(); } } else if (e == se_query_add) { auto_save_all(); return FALSE; } break; case DLG_USER: if (e == fe_button) { int err = 0; if (!save_sheet_line(err)) { if (err == NOT_TRANS) message_box("Messaggio ignorato in quanto transazione non riconosciuta"); else if (err == NOT_GEST) { TSheet_field& sf = sfield(F_MESSAGES); TMask& m = sf.sheet_mask(); error_box("Definire il programma gestore del file %s", (const char*)m.get(F_SUBJECT)); } else message_box("Messaggio non elaborato a causa di un errore (n.ro %d)", err); } } break; case DLG_SAVEREC: if (e == fe_button && jolly == 0) { if (curr_page() == 0) save_all_lines(); else save(); } break; case DLG_DELREC: if (e == fe_button) { if (jolly == 0) { test_delete(); fill_messages(); return FALSE; } } break; case F_FILE: if (jolly == 3) { if (e == fe_button) { TMask& m = o.mask(); TArray_sheet sht(-1,-1,-4,-4,"Selezione archivio", "Codice@6R|Descrizione archivio@70"); const TPrefix& pref = prefix(); const int total = pref.items(); if (total > 0) { TWait_cursor hourglass; for (int i = LF_USER; i < total; i++) { TToken_string* row = new TToken_string; *row << i; row->add(pref.description(*row)); sht.rows_array().add(row); } sht.select(m.get_int(o.dlg()) - LF_USER); } if (sht.run() == K_ENTER) m.set(o.dlg(), sht.selected() + LF_USER); } } break; case F_EXPR: if (jolly == 3) { if (e == fe_modify || e == fe_close) { TAutomask& m = (TAutomask&)o.mask(); const int num = m.get_int(F_FILE); TFilter_expr expr(m, num, o.get()); return expr.error() == 0; } } break; case DLG_DELLOG: if (e == fe_button) { TBrowsefile_field& bf = (TBrowsefile_field&)field(F_LOG); TViswin& vv = bf.vis_win(); vv.destroy_lines(); } break; case DLG_PRINT: if (e == fe_button) { TBrowsefile_field& bf = (TBrowsefile_field&)field(F_LOG); TViswin& vv = bf.vis_win(); vv.text().print(); return FALSE; // Don't close } break; default: break; } return TRUE; } void TMailer_mask::save_sheet(TConfig& ini, short dlg, const char* var) const { TSheet_field& sf = sfield(dlg); FOR_EACH_SHEET_ROW(sf, r, row) ini.set(var, *row, NULL, TRUE, r); } void TMailer_mask::load_sheet(TConfig& ini, short dlg, const char* var) { TSheet_field& sf = sfield(dlg); sf.destroy(); for (int r = 0; ini.exist(var, r); r++) sf.row(r) = ini.get(var, NULL, r); } void TMailer_mask::auto_save_all() { if (_mail_semaphore == 0) { TSheet_field& sf = sfield(F_MESSAGES); #ifdef DBG if (sf.items() > 0 && yesno_box("Si desidera eliminare i messaggi processati?")) #endif test_delete(); fill_messages(); if (!field(F_TIMER).empty()) { if (sf.items() > 0) save_all_lines(); } } else NFCHECK("Can't save locked mail"); } void TMailer_mask::handler(WINDOW win, EVENT* ep) { if (ep->type == E_TIMER) { if (ep->v.timer.id == _timer_id) { _secs++; if (_secs >= get_long(F_TIMER) * 60) { _secs = 0L; if (_mail_semaphore == 0) auto_save_all(); } } } TAutomask::handler(win, ep); } void TMailer_mask::save() const { TConfig ini(CONFIG_DITTA, "MailTransactions"); ini.remove_all(); ini.set("Server", get(F_SERVER)); ini.set("User", get(F_USER)); ini.set("Password", encode(get(F_PASSWORD))); ini.set("Timer", get(F_TIMER)); save_sheet(ini, F_ADDRESSES, "Recipient"); save_sheet(ini, F_PARAMS, "Filter"); } void TMailer_mask::load() { TConfig ini(CONFIG_DITTA, "MailTransactions"); set(F_SERVER, ini.get("Server")); set(F_USER, ini.get("User")); set(F_PASSWORD, decode(ini.get("Password"))); set(F_TIMER, ini.get_int("Timer")); load_sheet(ini, F_ADDRESSES, "Recipient"); load_sheet(ini, F_PARAMS, "Filter"); } TMailer_mask::TMailer_mask() : TAutomask("ba7100a"), _timer_id(XVT_TIMER_ERROR), _mail_semaphore(0) { load(); if (user() != ::dongle().administrator()) { disable(- G_SUPERUSER); } TConfig c(CONFIG_DITTA, "ba7"); _sequential = c.get_bool("StopOnError"); } TMailer_mask::~TMailer_mask() { if (_timer_id != XVT_TIMER_ERROR) { xvt_timer_destroy(_timer_id); _timer_id = XVT_TIMER_ERROR; } save(); } /////////////////////////////////////////////////////////// // TMailer /////////////////////////////////////////////////////////// class TMailer : public TSkeleton_application { public: virtual void main_loop(); }; void TMailer::main_loop() { open_files(LF_USER, 0); TMailer_mask mm; mm.run(); } int ba7100(int argc, char* argv[]) { TMailer app; app.run(argc, argv, "Postino"); return 0; }