campo-sirio/include/postman.cpp
alex 6c73d4919e Patch level : xx.7.054
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :
Riportata la verione 1.7 patch 054 aga sul main trunk.


git-svn-id: svn://10.65.10.50/trunk@9656 c028cbd2-c16b-5b4b-a496-9718f37d4682
2001-04-30 15:04:10 +00:00

398 lines
9.0 KiB
C++
Executable File

#include <config.h>
#include <expr.h>
#include <golem.h>
#include <postman.h>
#include <prefix.h>
#include <recarray.h>
#include <relapp.h>
#include <scanner.h>
///////////////////////////////////////////////////////////
// TRecipient
///////////////////////////////////////////////////////////
class TRecipient : public TObject
{
TString _address;
TString _group;
TString _expr;
public:
const TString& address() const { return _address; }
const TString& group() const { return _group; }
void add_expr(char op, const TString& expr);
bool can_receive(const TRectype& rec) const;
virtual bool ok() const
{ return _address.not_empty() && _expr.not_empty(); }
TRecipient(const TToken_string& str);
virtual ~TRecipient() { }
};
TRecipient::TRecipient(const TToken_string& str)
{
str.get(0, _address);
str.get(1, _group);
}
void TRecipient::add_expr(char op, const TString& expr)
{
if (_expr.not_empty())
_expr << (op == 'A' ? "&&" : "||");
if (expr.blank())
_expr << 1;
else
_expr << '(' << expr << ')';
}
bool TRecipient::can_receive(const TRectype& rec) const
{
TExpression e(_expr, _strexpr, TRUE);
for (int v = 0; v < e.numvar(); v++)
{
const char* name = e.varname(v);
if (rec.exist(name))
e.setvar(name, rec.get(name));
else
e.setvar(name, "");
}
bool yes = e.as_bool();
return yes;
}
///////////////////////////////////////////////////////////
// TPostman
///////////////////////////////////////////////////////////
class TPostman : public TObject
{
long _firm;
bool _recipients_ok;
TArray _recipient;
TAssoc_array _expr;
protected:
void test_firm();
TRecipient& recipient(int r) const
{ return (TRecipient&)_recipient[r]; }
void add_expr(const TString& addr,
char op, const TString& expr);
void load_filters();
public:
bool can_dispatch_transaction(const TRectype& rec);
bool dispatch_transaction(const TRectype& rec,
const TFilename& name);
TExpression* get_filter_expr(const char* flt);
const char* get_filter(const char* flt);
bool user_can(const char* flt, const TRelation* rel);
TPostman();
virtual ~TPostman() { }
};
void TPostman::test_firm()
{
const long firm = prefix().get_codditta();
if (firm != _firm)
{
_firm = firm;
_recipients_ok = FALSE;
}
}
void TPostman::add_expr(const TString& addr,
char op, const TString& expr)
{
for (int r = _recipient.last(); r >= 0; r--)
{
TRecipient& rec = recipient(r);
if (rec.address() == addr)
{
rec.add_expr(op, expr);
break;
}
else
{
if (rec.group() == addr)
rec.add_expr(op, expr);
}
}
}
bool TPostman::can_dispatch_transaction(const TRectype& rec)
{
test_firm();
if (!_recipients_ok)
{
_recipients_ok = TRUE;
_recipient.destroy();
TConfig cfg(CONFIG_DITTA, "MailTransactions");
TAuto_token_string str;
TString addr, opr, expr;
// Costruisce la lista dei destinatari
for (int r = 0; cfg.exist("Recipient", r); r++)
{
str = cfg.get("Recipient", NULL, r);
TRecipient* rcp = new TRecipient(str);
_recipient.add(rcp);
}
// Costruisce i filtri per i destinatari
for (int f = 0; cfg.exist("Filter", f); f++)
{
str = cfg.get("Filter", NULL, f);
const int num = str.get_int(1);
if (num != rec.num()) continue;
str.get(0, addr);
str.get(2, opr);
str.get(3, expr);
add_expr(addr, opr[0], expr);
}
// Elimina destinatari inutili
for (int d = _recipient.last(); d >= 0; d--)
{
if (!recipient(d).ok())
_recipient.destroy(d, TRUE);
}
}
return _recipient.items() > 0;
}
bool TPostman::dispatch_transaction(const TRectype& rec,
const TFilename& name)
{
bool ok = can_dispatch_transaction(rec);
if (ok)
{
TToken_string dest;
for (int r = 0; r < _recipient.items(); r++)
{
const TRecipient& a = recipient(r);
if (a.can_receive(rec))
dest.add(a.address());
}
ok = dest.items() > 0;
if (ok)
{
TMail_message msg(dest.get(0));
for (const char* r = dest.get(1); r; r = dest.get())
msg.add_copy_recipient(r);
TString16 subject;
switch (rec.num())
{
case LF_TAB:
case LF_TABCOM:
case LF_TABGEN:
subject << rec.get("COD"); break;
default:
subject << rec.num();
}
msg.set_subject(subject);
TScanner trans(name);
while (trans.good())
{
TString& line = trans.line();
msg.add_line(line);
}
ok = msg.send(TRUE);
}
}
return ok;
}
void TPostman::load_filters()
{
TRecord_cache users(LF_USER);
TToken_string perm(4096, '\n');
TAuto_token_string row(80);
// Costruisce il nome dell'applicazione principale
TFilename app(main_app().argv(0));
app.ext("");
app = app.name();
for (int a = 1; a < main_app().argc(); a++)
{
row = main_app().argv(a);
if (row[0] != '/')
app << ' ' << row;
else
break;
}
// Stringhe delle espressioni i filtro
TAssoc_array expr;
// Scandisce l'albero degli utenti/gruppi
for (TString16 u = user(); u.not_empty() && !users.already_loaded(u); )
{
const TRectype& urec = users.get(u);
// Test di validita'del record da eseguire solo la prima volta
if (u == user() && !urec.exist("PERMISSION"))
break;
perm = urec.get("PERMISSION"); // Permessi del nodo corrente
if (!perm.blank())
{
FOR_EACH_TOKEN(perm, tok)
{
row = tok;
const TString80 appmod = row.get(0);
const bool is_mod = appmod.len() == 2;
// Il programma oppure il modulo corrispondono
if ((is_mod && app.compare(appmod, 2, TRUE) == 0) ||
app.compare(appmod, -1, TRUE) == 0)
{
TString80 key = row.get(2); key.trim(); // Tipo di filtro
row = row.get(); row.trim(); // Espressione di filtro
if (key.not_empty() && row.not_empty() && row != "1")
{
key.upper();
TString* str = (TString*)expr.objptr(key);
if (str == NULL)
{
str = new TString(row); // Crea una nuova stringa
expr.add(key, str);
}
else
{ // Somma alla stringa precendente
if (*str != "0") // Se sono FALSE lasciami stare
{
if (row != "0") // Se aggiungo qualcosa di non ovvio
{
str->insert("(", 0);
*str << ")AND(";
*str << row << ')';
}
else
*str = "0";
}
}
}
}
}
}
u = urec.get("GROUPNAME");
}
// Trasforma le stringhe in espressioni
FOR_EACH_ASSOC_STRING(expr, hash, key, str)
{
TExpression* e = new TExpression(str, _strexpr, TRUE);
_expr.add(key, e);
}
// Inserisce un elemento fasullo per segnalare l'avvenuta lettura
if (_expr.items() == 0)
_expr.add("", NULL);
}
TExpression* TPostman::get_filter_expr(const char* flt)
{
if (_expr.items() == 0)
load_filters();
TString80 f(flt); f.upper();
TExpression* e = (TExpression*)_expr.objptr(f);
return e;
}
const char* TPostman::get_filter(const char* flt)
{
TExpression* e = get_filter_expr(flt);
return e ? e->string() : NULL;
}
bool TPostman::user_can(const char* flt, const TRelation* rel)
{
bool yes_he_can = TRUE;
TExpression* e = get_filter_expr(flt);
if (e != NULL)
{
if (rel != NULL)
{
for (int i = e->numvar()-1; i >= 0; i--)
{
const TString& name = e->varname(i);
const TFieldref ref(name, 0);
const TString& val = ref.read(*rel);
e->setvar(name, val);
}
yes_he_can = e->as_bool();
}
else
{
if (e->numvar() == 0)
yes_he_can = e->as_bool();
}
}
return yes_he_can;
}
TPostman::TPostman() : _firm(-1), _recipients_ok(FALSE)
{
}
TPostman& postman()
{
static TPostman* _postman = NULL;
if (_postman == NULL)
_postman = new TPostman;
return *_postman;
}
///////////////////////////////////////////////////////////
// Public interface
///////////////////////////////////////////////////////////
bool can_dispatch_transaction(const TRectype& rec)
{
return postman().can_dispatch_transaction(rec);
}
bool dispatch_transaction(const TRectype& rec, const TFilename& name)
{
return postman().dispatch_transaction(rec, name);
}
const char* get_user_filter(const char* flt)
{
return postman().get_filter(flt);
}
const char* get_user_read_filter()
{
return get_user_filter("Lettura");
}
const char* get_user_write_filter()
{
return get_user_filter("Scrittura");
}
bool user_can_read(const TRelation* rel)
{
return postman().user_can("Lettura", rel);
}
bool user_can_write(const TRelation* rel)
{
return user_can_read(rel) && postman().user_can("Scrittura", rel);
}