520 lines
20 KiB
PHP
520 lines
20 KiB
PHP
<% /*
|
|
$Revision$
|
|
$Id$
|
|
|
|
File: common.inc
|
|
Description: Common code die vooraan elk bestand *wordt uitgevoerd*
|
|
We proberen op allerlei manieren te achterhalen of de gebruiker
|
|
bekend is. Zo niet dan doen we uiteindelijk een redirect naar
|
|
login.asp
|
|
Parameters: Voor het includen van dit bestand kun je nog wat globale variabelen zetten om
|
|
het gedrag te beinvloeden.
|
|
JSON_Result ==> Altijd JSON result (auto DOCTYPE_Disable)
|
|
DOCTYPE_Disable ==> Geen DOCTYPE header (voor JSON-requests)
|
|
LCL_Disable ==> Geen lcl's cachen
|
|
ANONYMOUS_Allowed ==> Voorkom redirect naar login.asp als niet ingelogd
|
|
FCLTEXPIRES ==> Zet expire tijd van pagina (anders -1)
|
|
LOGIN_try ==> Alleen vanuit LoginTry.asp==>geen redirect naar LoginTry.asp
|
|
DBUPGRADE ==> Alleen vanuit dbupgrade.asp==>geen redirect naar dbupgrade.asp
|
|
|
|
Context: vanuit ELK asp bestand
|
|
Note: Dus gebruik met mate
|
|
Setting gaan in default.inc
|
|
Functies gaan naar shared.inc
|
|
*/
|
|
|
|
Session("page_start") = (new Date()).getTime(); // kun je in AiAi logging terugvinden, interessant bij timeouts
|
|
|
|
// Diverse andere variabelen zijn afhankelijk van rooturl en vooral customerId. Héél vroeg bepalen dus!
|
|
var rooturl;
|
|
var customerId;
|
|
|
|
determineCustomerId(); // doet ook rooturl
|
|
|
|
if (typeof JSON_Result == "undefined")
|
|
JSON_Result = false;
|
|
|
|
if (String(Request.ServerVariables("HTTP_ACCEPT")).toLowerCase() == "application/json")
|
|
JSON_Result = true; // Als je het vraagt krijg je het ook
|
|
|
|
if (JSON_Result)
|
|
DOCTYPE_Disable = true;
|
|
|
|
if (typeof DOCTYPE_Disable == "undefined")
|
|
{
|
|
Response.write('<!DOCTYPE html>');
|
|
}
|
|
|
|
/* global */ __Logging = Session("logging") || 0; // Voor robuustheid extra vroeg
|
|
|
|
%>
|
|
<!-- #include file="json2.js" -->
|
|
<!-- #include file="default.inc" -->
|
|
<!-- #include file="locale.inc" -->
|
|
<!-- #include file="hookfunctions.inc" -->
|
|
<!-- #include file="shared.inc" -->
|
|
<%
|
|
// Nu hebben we customerId. Wel doen voor m_connections.inc
|
|
// zodat we tijdens database migratie ook offline kunnen zetten
|
|
if (Request.QueryString("forceonline").Count > 0)
|
|
Session("forceonline") = true;
|
|
var FCLToffline = null;
|
|
tryOffline(rooturl + "/cust/");
|
|
tryOffline(custpath + "/"); // deze is sterker
|
|
|
|
var fso = Server.CreateObject("Scripting.FileSystemObject");
|
|
CreateFullPath(shared.tempFolder()); // Voor als die er nog niet is
|
|
|
|
var db_schema = Application("SET_" + customerId + "_DB_SCHEMA");
|
|
var upgrade_script = Server.MapPath(rooturl+ '/appl/upg/') + '/DB{0}.sql'.format(db_schema);
|
|
if (typeof DBUPGRADE == "undefined" && fso.FileExists(upgrade_script))
|
|
{
|
|
Server.Execute(rooturl + "/appl/upg/dbupgrade.asp");
|
|
if (db_schema == Application("SET_" + customerId + "_DB_SCHEMA"))
|
|
{
|
|
var txt = "Fatal Facilitor error session {0} at {1}".format(Session.SessionID, toISODateTimeString(new Date()));
|
|
txt += "<br>Database schema number 'DB{0}' was not updated properly by {1}".format(db_schema, upgrade_script);
|
|
txt += "<br>Please contact Facilitor support";
|
|
txt += "<br>Unsupported: Temporarily remove {0}".format(upgrade_script);
|
|
if (Application("otap_environment") == "O")
|
|
{
|
|
txt += ("<br>Or: clear FAC_VERSION_UPGRADING");
|
|
txt += ("<br>Or: set FAC_VERSION_SCHEMA to value found at end of {0}".format(upgrade_script));
|
|
}
|
|
shared.simpel_page(txt);
|
|
}
|
|
}
|
|
%>
|
|
<!-- #include file="logger.inc" -->
|
|
<!-- #include file="m_connections.inc" -->
|
|
<!-- #include file="putorders.inc" -->
|
|
<!-- #include file="header.inc" -->
|
|
<!-- #include file="user.inc" -->
|
|
<%
|
|
|
|
// NLS_LANG moet altijd op de webserver op WE8MSWIN1252
|
|
Response.Codepage = 1252;
|
|
Response.Charset = 'windows-1252';
|
|
if (JSON_Result)
|
|
Response.ContentType = "application/json";
|
|
|
|
if (Request.QueryString("api2").Count == 1 && Request.QueryString("mode") == "attachment")
|
|
{
|
|
Response.CacheControl = "max-age=604800"; // 1 week voor api2 bijlagen
|
|
}
|
|
else
|
|
{
|
|
Response.Expires = this.FCLTEXPIRES||-1; // Do not cache our ASP files
|
|
|
|
if (!this.FCLTEXPIRES)
|
|
Response.CacheControl = "no-cache, no-store";
|
|
if (typeof NO_ADDHEADER == "undefined")
|
|
Response.AddHeader ("X-Content-Type-Options", "nosniff");
|
|
}
|
|
|
|
settings.loadSET();
|
|
device.init();
|
|
|
|
var overrule_lcl = {};
|
|
var overrule_setting = [];
|
|
function tryOverrule(path)
|
|
{
|
|
var fso = Server.CreateObject("Scripting.FileSystemObject");
|
|
var hookfile = Server.MapPath(path);
|
|
if (fso.FileExists(hookfile))
|
|
{
|
|
try
|
|
{
|
|
var hook = GetObject("script:"+hookfile);
|
|
}
|
|
catch (e)
|
|
{ // We zitten zéér ernstig in de problemen. Geen fancy AiAi gedoe
|
|
Response.Write("Unable to read " + hookfile + "<p/>");
|
|
Response.Write(e.description);
|
|
Response.End;
|
|
}
|
|
// Deze mag de hookfile gebruiken
|
|
hook.Overrule =
|
|
{
|
|
DEFAULT: function (naam, type, waarde)
|
|
{
|
|
overrule_setting.push({ naam: naam, type: type, waarde: waarde }); // Voor fac_verify
|
|
var v = Application("SET_DEFAULT_" + naam);
|
|
if (typeof v == "undefined" ||
|
|
type != Application("SET_T_" + naam) ||
|
|
waarde != Application("SET_DEFAULT_" + naam))
|
|
{
|
|
Application.Lock();
|
|
Application("SET_DEFAULT_" + naam) = waarde;
|
|
Application("SET_T_" + naam) = type; // Is voor alle klanten gelijk
|
|
Application.UnLock();
|
|
__SafeDoLog("Default for setting {0} ({1}) set to <em>{2}</em> by cust/custenv.wsc DEFAULT".format(naam, type, waarde), "#FF0000");
|
|
}
|
|
},
|
|
SET: function (naam, waarde)
|
|
{
|
|
settings.overrule_setting(naam.toLowerCase(), waarde);
|
|
},
|
|
LCL: function (naam, waarde)
|
|
{
|
|
overrule_lcl[naam] = waarde;
|
|
},
|
|
APPLICATION: function (naam, waarde)
|
|
{
|
|
if (Application(naam) != waarde)
|
|
{
|
|
Application.Lock();
|
|
Application(naam) = waarde;
|
|
Application.UnLock();
|
|
}
|
|
}
|
|
}
|
|
// Deze mogen de hookfiles gebruiken
|
|
// Moet je ze wel in de wsc opnemen bij de properties
|
|
hook.Oracle = Oracle;
|
|
hook.__Log = __Log;
|
|
hook.__DoLog = __DoLog;
|
|
hook.safe = safe;
|
|
// Met onderstaande kun je zeer foute trucs uithalen
|
|
// Gedacht scenario: bijvoorbeeld in een testomgeving bij bepaalde
|
|
// requests (API's) gericht logging aanzetten zonder bestanden
|
|
// te hoeven wijzigen.
|
|
var aspdata = { Application: Application,
|
|
Request: Request,
|
|
Session: Session,
|
|
Request: Request,
|
|
Response: Response,
|
|
Server: Server
|
|
};
|
|
var realuser = Session("fclt_realuser"); // De Windows user, niet noodzakelijkerwijs de FACILITOR user
|
|
if (realuser)
|
|
{
|
|
aspdata.Username = realuser.split("\\").pop();
|
|
if (realuser.split("\\").length > 1)
|
|
aspdata.Userdomain = realuser.split("\\")[0];
|
|
}
|
|
|
|
hook.custenv(aspdata);
|
|
hook = null; // zorg dat de GC het object kan opruimen.
|
|
}
|
|
}
|
|
|
|
// Optionele overrules in cust/custenv.wsc en cust/XXXX/custenv.inc
|
|
tryOverrule(rooturl + "/cust/custenv.wsc");
|
|
tryOverrule(custpath + "/custenv.wsc"); // deze is sterker
|
|
|
|
// Plaats een offline.html bestandje in /cust/ of /cust/XXXX en de site gaat offline
|
|
// Door url uit te breiden met ?forceonline=1 kun je toch naar binnen
|
|
// Wat met API's?
|
|
function tryOffline(path)
|
|
{
|
|
var fso = Server.CreateObject("Scripting.FileSystemObject");
|
|
var offlinefile = Server.MapPath(path + "offline.html");
|
|
var forceonlinefile = Server.MapPath(custpath + "/forceonline.txt");
|
|
if (fso.FileExists(offlinefile) && !fso.FileExists(forceonlinefile))
|
|
{
|
|
Response.AddHeader("FCLT-Offline","offline");
|
|
/* global */ FCLToffline = offlinefile;
|
|
if (typeof Session("forceonline") != "undefined")
|
|
return;
|
|
|
|
// Geen Response.Redirect. Dan kan de gebruiker geen F5 drukken om weer verbinding te krijgen na een tijdje
|
|
var ftekst = fso.OpenTextFile(offlinefile);
|
|
var tekst = ftekst.ReadAll();
|
|
ftekst.Close();
|
|
if (JSON_Result || getQParam("API2","")) // Bij API2 is onze JSON_Result vaak nog niet gezet
|
|
{
|
|
Response.Status = "503 Service Unavailable";
|
|
// Windows 2012 stuurt de volgende body doorgaans niet meer!
|
|
// JSON.stringfy hebben we (nog!) niet gegarandeerd dus simpel houden
|
|
Response.Write(tekst);
|
|
Response.End;
|
|
}
|
|
else
|
|
{
|
|
shared.simpel_page(tekst);
|
|
}
|
|
}
|
|
}
|
|
|
|
// ip-restrictie controle
|
|
var ips = S("sys_ip_restrict");
|
|
if (ips)
|
|
{
|
|
var ip = String(Request.ServerVariables("REMOTE_HOST"));
|
|
var ips_intern = S("sys_ip_restrict_internal");
|
|
if (!new RegExp(ips.replace(/\./ig, "\\."), "ig").test(ip) &&
|
|
!(ips_intern && new RegExp(ips_intern.replace(/\./ig, "\\."), "ig").test(ip)))
|
|
{
|
|
Response.write ("Forbidden: IP address of the client has been rejected." ); // Doet IIS bij echte restrictie
|
|
Response.Status = "403.6";
|
|
Response.end;
|
|
}
|
|
}
|
|
|
|
if (S("hiresTimer"))
|
|
{
|
|
try // Dit is de allereerste code die ontdekt dat de DLL niet is geladen. Daarom nette foutmelding
|
|
{
|
|
hiresTimer = new ActiveXObject("SLNKDWF.About");
|
|
}
|
|
catch(e)
|
|
{
|
|
abort_with_warning("SLNKDWFx64.DLL not properly installed.\n{0}".format(e.description));
|
|
}
|
|
}
|
|
|
|
if (S("auto_https") && Request.ServerVariables("SERVER_PORT") != "443")
|
|
{
|
|
Response.Redirect("https://" + Request.ServerVariables("SERVER_NAME") + rooturl + "?" + Request.ServerVariables("QUERY_STRING"));
|
|
Response.End;
|
|
}
|
|
else
|
|
{ // 0 wordt ook ondersteund om het actief uit te schakelen
|
|
if (typeof NO_ADDHEADER == "undefined" && S("hsts_maxage") >= 0 && Request.ServerVariables("SERVER_PORT") != "80")
|
|
Response.AddHeader("Strict-Transport-Security", "max-age=" + S("hsts_maxage")); // Geen includeSubDomains, dat nekt http://facilitor.nl
|
|
}
|
|
|
|
// Merk op: door onze Server.Transfer's met API's of inloggen zie je in Fiddler wel
|
|
// eens dat X-Frame-Options twee keer in de header komt. Slordig maar acceptabel.
|
|
if (typeof NO_ADDHEADER == "undefined" && !S("allow_framed_facilitor"))
|
|
Response.AddHeader ("X-Frame-Options", "sameorigin"); // voorkom ClickJacking
|
|
|
|
if (typeof NO_ADDHEADER == "undefined" && S("csp_header") && S("csp_header") != "X")
|
|
{
|
|
if (this.CSP_EXTRADATA) // sta openstreemap tiles toe
|
|
var csp_header = S("csp_header").format(S("csp_header_extradata"));
|
|
else
|
|
var csp_header = S("csp_header").format("");
|
|
Response.AddHeader("Content-Security-Policy", csp_header);
|
|
}
|
|
|
|
if (typeof NO_ADDHEADER == "undefined" && S("referrer_policy_header") && S("referrer_policy_header") != "X")
|
|
Response.AddHeader("Referrer-Policy", S("referrer_policy_header"));
|
|
|
|
protectHMAC.getProtectSecret(); // forceer eerste keer per dag
|
|
|
|
var fixcookie = String(Request.Cookies("ASPFIXATION"));
|
|
if (fixcookie)
|
|
{
|
|
var fixCustid = fixcookie.substr(0, customerId.length);
|
|
if ( fixCustid != customerId)
|
|
{ // reset ingelogde user, customer wissel?
|
|
Session("user_key")=user_key=-1;
|
|
}
|
|
}
|
|
|
|
// Zie login.inc: ga ASP Session Fixation tegen.
|
|
if (typeof Session("ASPFIXATION") != "undefined")
|
|
{
|
|
var fixcookie = Request.Cookies("ASPFIXATION");
|
|
if (Session("ASPFIXATION") != fixcookie)
|
|
{
|
|
// Simuleer logoff
|
|
var ident = "&ident=" + customerId + "\\" + Session("user_key");
|
|
if (Session("login_date"))
|
|
{
|
|
ident += "&login_date=" + toISODateTimeString(new Date(Session("login_date")))
|
|
}
|
|
Session("user_key")=user_key=-1; // geen remove hier, anders grijpt SSO direct weer in
|
|
setASPFIXATION(); // zet nieuwe cookie
|
|
Response.Redirect(rooturl + "/appl/shared/expired.asp?aspfixation=1" + ident); // ident zodat we wel weten *wie* dit overkomt
|
|
}
|
|
}
|
|
else
|
|
setASPFIXATION(); // eerste keer
|
|
|
|
if (S("sys_ip_lockmode") > 0)
|
|
{
|
|
var ip = String(Request.ServerVariables("REMOTE_ADDR"));
|
|
// We zijn relatief flexibel: de laatste 16 bit wijzigen staan we toe
|
|
// Deze bescherming tegen session hijacking is dus maar heel beperkt
|
|
if (IP.isIPv4(ip) && Session("last_ip") && Session("last_ip") != ip && !IP.inSubnet(Session("last_ip"), ip + "/16"))
|
|
{
|
|
var agent = String(Request.ServerVariables("HTTP_USER_AGENT"));
|
|
shared.auditfail(L("lcl_autfai_ipchange").format(Session("last_ip"), ip, Session("userident"), agent), "#0ff");
|
|
// Simuleer logoff
|
|
Session.Contents.Remove("last_ip");
|
|
Session("user_key")=user_key=-1; // geen remove hier, anders grijpt SSO direct weer in
|
|
}
|
|
}
|
|
|
|
|
|
// Zijn we bekend? Zo niet dan naar login.asp om dat uit te zoeken
|
|
var user_key = Session("user_key") || -1;
|
|
|
|
var user_allowed = Session("locked_user_allowed") || [];
|
|
|
|
if (user_key < 0 && typeof LOCKED_USER_OK != "undefined" && user_allowed.length) // Is de huidige pagina geschikt voor locked users?
|
|
{
|
|
for (var i = 0; i < user_allowed.length; i++)
|
|
{
|
|
if (LOCKED_USER_OK === true ||
|
|
(user_allowed[i].xmlnode == LOCKED_USER_OK.xmlnode &&
|
|
user_allowed[i].key == LOCKED_USER_OK.key))
|
|
{
|
|
var user_key = user_allowed[i].locked_user_key;
|
|
Session("user_lang") = "NL";
|
|
Session("time_zone") = "Europe/Amsterdam"
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
var user; // wordt bij geldige user gevuld met new Perslid
|
|
|
|
if ((user_key < 0 || getQParamInt("jwtforce", 0) == 1) && typeof LOGIN_try == "undefined")
|
|
{
|
|
Server.Execute(rooturl + "/appl/aut/loginTry.asp"); // Laat die het eens proberen op te lossen
|
|
if (Session("user_key") > 0)
|
|
{
|
|
__Logging = Session("logging") || 0; // kan gezet geraakt zijn in loginTry.asp als prs_perslid_loglevel
|
|
user_key = Session("user_key");
|
|
}
|
|
}
|
|
|
|
if (user_key < 0 && typeof ANONYMOUS_Allowed == "undefined")
|
|
{
|
|
var method = String(Request.ServerVariables("REQUEST_METHOD"));
|
|
if (method == "HEAD" || method == "OPTIONS" || method == "PROPFIND")
|
|
{ // Een HEAD zonder cookies is waarschijnlijk afkomstig van Excel
|
|
// met agent 'Microsoft+Office+Existence+Discovery'
|
|
// Door de '405' heeft hij hopelijk door dat we echt geen WEBDAV doen
|
|
Response.Status = "405 Method not allowed";
|
|
Response.End;
|
|
}
|
|
|
|
if (JSON_Result) // Login scherm werkt toch niet
|
|
{
|
|
Response.Clear();
|
|
// JSON.stringfy hebben we (nog!) niet gegarandeerd dus maar poor-man stringify
|
|
Response.Write('{"warning":"'+L("lcl_not_loggedin").replace(/\n/g,"\\n").replace(/\"/g,"\\\"") +'","success":false}');
|
|
Response.End;
|
|
}
|
|
|
|
if (getQParamInt("nosso", "0") == 1) // Weiger alle automatische varianten
|
|
{
|
|
Response.Status = "401 Unauthorized";
|
|
Response.End;
|
|
}
|
|
|
|
var url = Session("unauth_url") || S("login_url"); // unauth_url uit shorturl.asp
|
|
if (url == 'appl/shared/login.asp') // even compatible blijven
|
|
url = 'appl/aut/login.asp';
|
|
|
|
if (getQParam("sso", "") == "0") // forceer de default
|
|
url = 'appl/aut/login.asp';
|
|
|
|
if (!url.match(/^http/))
|
|
var url = rooturl + "/" + url; // "appl/shared/login.asp";
|
|
var ret_page = "";
|
|
if (String(Request.ServerVariables("REQUEST_METHOD")) == "GET")
|
|
{
|
|
ret_page = String(Request.ServerVariables("SCRIPT_NAME"));
|
|
ret_page = ret_page.replace(/\/default.asp$/i, "/");
|
|
}
|
|
|
|
var qs = String(Request.ServerVariables("QUERY_STRING"));
|
|
if ((qs && qs != 'fac_id=' + customerId) || (ret_page && ret_page != rooturl + "/"))
|
|
{
|
|
url = protectQS.create(url + "?querystring=" + Server.URLencode(qs)
|
|
+ "&ret_page=" + Server.URLencode(ret_page));
|
|
}
|
|
Response.Redirect(url);
|
|
}
|
|
|
|
if (user_key > 0)
|
|
{
|
|
if (typeof REGISTERMENU_Disable == "undefined")
|
|
{
|
|
var from_menu_key = getQParamInt("from_menu_key", -1);
|
|
if (from_menu_key > 0)
|
|
{
|
|
shared.registeraction("menu", {refkey: from_menu_key, daily: S("fac_gui_counter_menu_daily")});
|
|
}
|
|
}
|
|
|
|
var from_search_key = getQParamInt("from_search_key", -1);
|
|
if (from_search_key > 0)
|
|
{
|
|
var url = String(Request.ServerVariables("SCRIPT_NAME"))
|
|
+ "?" + String(Request.ServerVariables("QUERY_STRING"));
|
|
url = url.replace("&from_search_key=" + from_search_key, ""); // Dat hoeven we er niet in te hebben
|
|
if (url.indexOf(rooturl) == 0)
|
|
url = url.substr(rooturl.length + 1);
|
|
shared.registeraction("searchchoice", { refkey: from_search_key, info: url });
|
|
}
|
|
|
|
if (typeof NO_ADDHEADER == "undefined" && Request.Servervariables("HTTP_FCLT_VERSION").Count > 0)
|
|
{ // wordt opgepikt door FCLTAPI.DLL voor in de logging en daarna gestript. Niet in Fiddler dus
|
|
Response.AddHeader ("FCLT_USERID", customerId + "\\" + String(user_key));
|
|
}
|
|
Session.Contents.Remove("fallback_user_key"); // uit shorturl.asp. Ondertussen niet meer nodig
|
|
Session.Contents.Remove("unauth_url"); // uit shorturl.asp. Ondertussen niet meer nodig
|
|
|
|
/* global */ user = new Perslid(user_key);
|
|
if (typeof NO_OTP_OK == "undefined" && typeof ANONYMOUS_Allowed == "undefined")
|
|
{
|
|
if (Session("must_set_otp") == 1)
|
|
Response.Redirect(rooturl + "/appl/prs/prs_perslid_otp_new.asp?prs_key=" + user_key);
|
|
}
|
|
if (typeof EXPIRED_PASSWORD_OK == "undefined" && typeof ANONYMOUS_Allowed == "undefined")
|
|
{
|
|
if (Session("must_reset_password") == 1)
|
|
{
|
|
Response.Redirect(rooturl + "/appl/prs/pchange.asp?expired=1");
|
|
}
|
|
if (user.credentials_changed())
|
|
{
|
|
// login.inc is niet standaard included dus kan ik geen doLogoff() doen
|
|
// Dit triggert echter de rest wel?
|
|
Session.Contents.Remove("user_key");
|
|
}
|
|
}
|
|
|
|
if (Session("must_accept_terms") == 1
|
|
&& typeof TERMS_CONDITIONS_OK == "undefined")
|
|
{
|
|
Response.Redirect(rooturl + "/appl/prs/terms.asp");
|
|
}
|
|
|
|
CheckForLogging(Request.QueryString("LOGGING"));
|
|
}
|
|
else // zitten we in een bestand wat het user-object nooit benadert
|
|
{ // Wel een dummy user object aanmaken om de ergste AiAi's
|
|
// op http://xxxx.facilitor.nl/api2/departments/ te voorkomen
|
|
var user = { checkAutorisation: function ()
|
|
{
|
|
Response.Status = "401 Unauthorized";
|
|
Response.End;
|
|
}
|
|
}
|
|
user.has = user.checkAutorisation;
|
|
}
|
|
|
|
// Zorg dat dit de *allerlaatste* functie is die je op een asp pagina aanroept.
|
|
// En/of plaats dit vlak voor een Response.End of een Response.Redirect
|
|
function ASPPAGE_END()
|
|
{
|
|
if (__Logging > 0)
|
|
{
|
|
var now = new Date();
|
|
var start = new Date(Session("page_start"));
|
|
var duration = now.getTime() - start.getTime();
|
|
// _sql_cnt en _sql_time worden in m_connections.inc bijgehouden
|
|
var txt = "Page took {0} seconds ({1} sql={2}s, nonsql={3}s, log overhead={4}s)"
|
|
.format(Math.round(duration / 10) / 100,
|
|
_sql_cnt,
|
|
Math.round(_sql_time / 10) / 100,
|
|
Math.round((duration - _sql_time - _logger_time) / 10) / 100,
|
|
Math.round(_logger_time / 10) / 100);
|
|
__Log(txt);
|
|
|
|
check_recordsets(); // laatste sluiten
|
|
dump_recordsets();
|
|
}
|
|
|
|
Oracle.RealConnection.Close();
|
|
}
|
|
|
|
%> |