#include #include #include #include #include // 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

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 if (!async && utente) { if (dongle().local()) // Rilascio la chiave il prima possibile 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 (dongle().local()) 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) { }