campo-sirio/include/execp.cpp

173 lines
5.1 KiB
C++
Executable File

#include <xvt.h>
#include <config.h>
#include <dongle.h>
#include <execp.h>
#include <recarray.h>
#include <user.h>
// Il programma attuale NON e' ne' ba0 ne ba1 e si usa il menu in stile Outlook?
static bool is_outlook_menu_chain()
{
const TFilename n = __argv[0];
const TString& app = n.name_only();
if (app.match("ba[0,1]", true) != 0)
return false;
return ini_get_int(CONFIG_GUI, "Colors", "TreeView") == 3;
}
// @doc EXTERNAL
// @mfunc Esegue il processo
//
// @rdesc Ritorna il codice di uscita del processo (0 in caso di errore).
long TExternal_app::run(
bool async, // @parm Per eseguire il processo in parallelo
byte utente, // @parm Permette di inserire il nome dell'utente nella riga di comando
bool iconize) // @parm Iconizza il programma chiamante
// @comm Se <p asyn> e' FALSE aspetta che termini il processo in esecuzione prima di iniziare il nuovo
{
TFilename path(_path);
TFilename comm_name(_path);
//se c'e' - o / tronca il nome allo spazio precedente
const int pm = comm_name.find(" -"); //c'e' un - nella stringa?
const int ps = comm_name.find(" /"); //c'e' un / nella stringa?
int params = -1;
if (pm > 0 && (pm < ps || ps <= 0))
params = pm; else
if (ps > 0)
params = ps;
if (params > 0)
comm_name.cut(params);
if (*comm_name.ext() == '\0') // se non c'e' estensione ci mette .exe (sono programmi)
comm_name.ext("exe");
const bool found = comm_name.custom_path(); //cerca il file in custom o in locale
if (utente == 1) // utente puo' essere 0 = No, 1 = Si, 3 = Forzatura
{
const TString& name = comm_name.name_only();
bool our_app = name.len() > 2;
if (our_app && atoi(name) < 70)
{
our_app = (isalpha(name[0]) && isalpha(name[1])) &&
(isdigit(name[2]) || name.ends_with("cnv"));
}
if (!our_app) // Non e' un programma di campo per cui ...
utente = 0; // ... non aggiungo il codice utente al comando
}
if (found)
{
path = comm_name;
if (params > 0)
path << _path.mid(params);
}
if (utente && path.find(" /u") < 0)
path << " /u" << user();
// save cwd
DIRECTORY oldir; xvt_fsys_get_dir(&oldir);
if (!utente && found) // cambio directory se eseguo un programma estero
{
TFilename dir(path.path());
if (dir.full())
{
DIRECTORY d;
if (xvt_fsys_convert_str_to_dir(dir, &d))
xvt_fsys_set_dir(&d);
}
}
TString256 old_title; // Vecchio titolo della finestra principale
bool close_all = false; // Chiudi tutti i file in caso di manutenzione
bool login_needed = false;
if (!async && utente)
{
// Rilascio la chiave hardware (Eutron o Hardlock) il prima possibile
// Network e SSA non hanno bisogno di questo accorgimento
if (dongle().hardware() < _dongle_network)
login_needed = dongle().logout();
close_all = _path.starts_with("ba1 -0") && prefix_valid();
if (close_all) //se lancia la gestione archivi forza la chiusura dei files e pure dei tracciati!
prefix().set("");
else
safely_close_closeable_isamfiles();
// Programma normale (non menu) che chiama "collega"
if (iconize && is_outlook_menu_chain())
{
xvt_vobj_get_title(TASK_WIN, old_title.get_buffer(), old_title.size());
xvt_vobj_set_title(TASK_WIN, __MAGIC_CAPTION__);
iconize = false;
}
}
_exitcode = xvt_sys_execute(path, !async, iconize);
if (old_title.full()) // Rimetto le cose a posto
xvt_vobj_set_title(TASK_WIN, old_title);
// restore cwd
xvt_fsys_set_dir(&oldir);
// Ignora volutamente il return code da HL_LOGIN(). Se va bene riprende il posto
// altrimenti fa lo stesso. Infatti puo' capitare con una chiave di rete, che
// nel lasso di tempo trascorso dalla HL_LOGOUT() dell'applicazione chiamata,
// a questa HL_LOGIN() [approssimativamente qualche decimo di secondo], qualche altro
// programma si inserisca, occupando magari anche l'ultimo posto disponibile.
// Quindi se si verificasse tale sfigatissima condizione, sicuramente
// non ci saranno piu' posti liberi nell'HL_server: il programma comunque non
// puo' interrompersi a meta'; ecco perche il valore di ritorno di HL_LOGIN viene
// ignorato.
if (!async && utente)
{
if (login_needed)
dongle().login();
if (close_all) //se lancia la gestione archivi forza la riapertura dei files e pure dei tracciati!
prefix().set("DEF"); //..li aveva chiusi qualche riga sopra
}
return _exitcode;
}
bool TExternal_app::can_run() const
{
if (*prefix().name() <= '.')
return true;
const TString& usr = user();
if (usr.blank() || usr == dongle().administrator())
return true;
const TString_array& uag = user_and_groups();
TToken_string perm(255, '\n'), row(80,SAFE_PIPE_CHR);
FOR_EACH_ARRAY_ROW(uag, i, rec)
{
perm = rec->after(rec->separator());
if (perm.full())
{
FOR_EACH_TOKEN(perm, tok)
{
row = tok;
if (_path.compare(row.get(0), -1, true) == 0 && row.get_char(1) == 'N')
return false;
}
}
}
return true;
}
TExternal_app::TExternal_app(const char* p)
: _path(p), _exitcode(0)
{
}