#include #include #include #include #include // @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); const int p = comm_name.find(" -"); //c'e' uno spazio nella stringa? if (p > 0) //se c'e' tronca il nome allo spazio comm_name.cut(p); 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 TString name(comm_name.name()); if (utente == 1) // utente puo' essere 0 = No, 1 = Si, 3 = Forzatura { bool our_app = name.len() > 2; if (our_app && atoi(name) < 70) { our_app = isalpha(name[0]) && isalpha(name[1]) && isdigit(name[2]); } if (!our_app) utente = false; } if (found && p > 0) { path = comm_name; path << _path.mid(p); } if (utente) path << " /u" << user(); // save cwd DIRECTORY oldir; xvt_fsys_get_dir(&oldir); if (!utente) // cambio directory se eseguo un programma estero { const TFilename dir(comm_name.path()); if (dir.not_empty() && dir.find("custom") < 0) { DIRECTORY d; if (xvt_fsys_convert_str_to_dir((char*)(const char*)dir, &d)) xvt_fsys_set_dir(&d); } } const bool close_all = !async && _path.starts_with("ba1 -0") && prefix_valid(); if (!async) { if (close_all) //se lancia la gestione archivi forza la chiusura dei files e pure dei tracciati! prefix().set(""); else safely_close_closeable_isamfiles(); if (dongle().local()) dongle().logout(); } // iconize &= !async && show; // _exitcode = os_execute(path, !async, iconize, show); _exitcode = xvt_sys_execute(path, !async, iconize); // 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) { 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 TLocalisamfile test(LF_USER); if (test.curr().exist("PERMISSION")) { TRecord_cache utonti(LF_USER); // Non uso cache() per problemi durante conversioni TToken_string perm(4096, '\n'), row(80,SAFE_PIPE_CHR); for (TString16 u = user(); u.not_empty(); u = utonti.get(u, "GROUPNAME")) { if (utonti.already_loaded(u)) { NFCHECK("L'utente %s ha dei permessi ricorsivi", (const char*)u); break; } perm = utonti.get(u, "PERMISSION"); if (!perm.blank()) { FOR_EACH_TOKEN(perm, tok) { row = tok; if (_path == row.get(0)) // Il nome corrisponde { if (*row.get(1) == 'N') return FALSE; } } } } } return TRUE; } TExternal_app::TExternal_app(const char* p) : _path(p), _exitcode(0) { }