Lines 101-106
Link Here
|
101 |
|
101 |
|
102 |
mod_rivet_globals* rivet_module_globals = NULL; |
102 |
mod_rivet_globals* rivet_module_globals = NULL; |
103 |
|
103 |
|
|
|
104 |
/* -- Rivet_PrintErrorMessage |
105 |
* |
106 |
* Utility function to print the error message stored in errorInfo |
107 |
* with a custom header. This procedure is called to print standard |
108 |
* errors when one of Tcl scripts fails |
109 |
* |
110 |
* Arguments: |
111 |
* |
112 |
* - Tcl_Interp* interp: the Tcl interpreter that was running the script |
113 |
* (and therefore the built-in variable errorInfo |
114 |
* keeps the message) |
115 |
* - const char* error: Custom error header |
116 |
*/ |
117 |
|
118 |
static void |
119 |
Rivet_PrintErrorMessage (Tcl_Interp* interp,const char* error_header) |
120 |
{ |
121 |
Tcl_Obj* errormsg = Tcl_NewObj(); |
122 |
|
123 |
Tcl_IncrRefCount(errormsg); |
124 |
Tcl_AppendStringsToObj(errormsg,"puts \"",error_header,"<br />\"\n",NULL); |
125 |
Tcl_AppendStringsToObj(errormsg,"puts \"<pre>$errorInfo</pre>\"\n",NULL); |
126 |
Tcl_EvalObjEx(interp,errormsg,0); |
127 |
Tcl_DecrRefCount(errormsg); |
128 |
} |
129 |
|
104 |
/* |
130 |
/* |
105 |
* -- Rivet_chdir_file (const char* filename) |
131 |
* -- Rivet_chdir_file (const char* filename) |
106 |
* |
132 |
* |
Lines 299-304
Link Here
|
299 |
} |
325 |
} |
300 |
} |
326 |
} |
301 |
|
327 |
|
|
|
328 |
/* -- Rivet_ExecuteErrorHandler |
329 |
* |
330 |
* Invoking either the default error handler or the ErrorScript. |
331 |
* In case the error handler fails a standard error message is printed |
332 |
* (you're better off if you make your error handlers fail save) |
333 |
* |
334 |
* Arguments: |
335 |
* |
336 |
* - Tcl_Interp* interp: the Tcl interpreter |
337 |
* - Tcl_Obj* tcl_script_obj: the script that failed (to retrieve error |
338 |
* info from it |
339 |
* - request_rec* req: current request obj pointer |
340 |
* |
341 |
* Returned value: |
342 |
* |
343 |
* - A Tcl status |
344 |
*/ |
345 |
|
346 |
static int |
347 |
Rivet_ExecuteErrorHandler (Tcl_Interp* interp,Tcl_Obj* tcl_script_obj, request_rec* req) |
348 |
{ |
349 |
int result; |
350 |
rivet_server_conf* conf = Rivet_GetConf(req); |
351 |
Tcl_Obj* errscript; |
352 |
|
353 |
/* We extract information from the errorOutbuf variable. Notice that tcl_script_obj |
354 |
* can either be the request processing script or conf->rivet_abort_script |
355 |
*/ |
356 |
|
357 |
Tcl_SetVar( interp, "errorOutbuf",Tcl_GetStringFromObj( tcl_script_obj, NULL ),TCL_GLOBAL_ONLY ); |
358 |
|
359 |
/* If we don't have an error script, use the default error handler. */ |
360 |
if (conf->rivet_error_script) { |
361 |
errscript = conf->rivet_error_script; |
362 |
} else { |
363 |
errscript = conf->rivet_default_error_script; |
364 |
} |
365 |
|
366 |
Tcl_IncrRefCount(errscript); |
367 |
result = Tcl_EvalObjEx(interp, errscript, 0); |
368 |
if (result == TCL_ERROR) { |
369 |
Rivet_PrintErrorMessage(interp,"<b>Rivet ErrorScript failed</b>"); |
370 |
} |
371 |
|
372 |
/* This shouldn't make the default_error_script go away, |
373 |
* because it gets a Tcl_IncrRefCount when it is created. |
374 |
*/ |
375 |
Tcl_DecrRefCount(errscript); |
376 |
|
377 |
return result; |
378 |
} |
379 |
|
380 |
|
302 |
/* -- Rivet_ExecuteAndCheck |
381 |
/* -- Rivet_ExecuteAndCheck |
303 |
* |
382 |
* |
304 |
* Tcl script execution central procedure. The script stored |
383 |
* Tcl script execution central procedure. The script stored |
Lines 316-322
Link Here
|
316 |
* |
395 |
* |
317 |
* Returned value: |
396 |
* Returned value: |
318 |
* |
397 |
* |
319 |
* - invariably TCL_OK |
398 |
* - One of the Tcl defined returned value of Tcl_EvelObjExe (TCL_OK, |
|
|
399 |
* TCL_ERROR, TCL_BREAK etc.) |
320 |
* |
400 |
* |
321 |
* Side effects: |
401 |
* Side effects: |
322 |
* |
402 |
* |
Lines 330-336
Link Here
|
330 |
{ |
410 |
{ |
331 |
int result; |
411 |
int result; |
332 |
rivet_server_conf* conf = Rivet_GetConf(req); |
412 |
rivet_server_conf* conf = Rivet_GetConf(req); |
333 |
rivet_interp_globals* globals = Tcl_GetAssocData(interp, "rivet", NULL); |
|
|
334 |
|
413 |
|
335 |
Tcl_Preserve (interp); |
414 |
Tcl_Preserve (interp); |
336 |
result = Tcl_EvalObjEx(interp, tcl_script_obj, 0); |
415 |
result = Tcl_EvalObjEx(interp, tcl_script_obj, 0); |
Lines 337-343
Link Here
|
337 |
|
416 |
|
338 |
if (result == TCL_ERROR) { |
417 |
if (result == TCL_ERROR) { |
339 |
|
418 |
|
340 |
Tcl_Obj* errscript; |
|
|
341 |
Tcl_Obj* errorCodeListObj; |
419 |
Tcl_Obj* errorCodeListObj; |
342 |
Tcl_Obj* errorCodeElementObj; |
420 |
Tcl_Obj* errorCodeElementObj; |
343 |
char* errorCodeSubString; |
421 |
char* errorCodeSubString; |
Lines 376-414
Link Here
|
376 |
{ |
454 |
{ |
377 |
if (conf->rivet_abort_script) |
455 |
if (conf->rivet_abort_script) |
378 |
{ |
456 |
{ |
379 |
if (Tcl_EvalObjEx(interp,conf->rivet_abort_script,0) == TCL_ERROR) |
457 |
|
|
|
458 |
/* Ideally an AbortScript should be fail safe, but in case |
459 |
* it fails we give a chance to the subsequent ErrorScript |
460 |
* to catch this error. |
461 |
*/ |
462 |
|
463 |
result = Tcl_EvalObjEx(interp,conf->rivet_abort_script,0); |
464 |
if (result == TCL_ERROR) |
380 |
{ |
465 |
{ |
381 |
CONST84 char *errorinfo = Tcl_GetVar( interp, "errorInfo", 0 ); |
466 |
|
382 |
TclWeb_PrintError("<b>Rivet AbortScript failed!</b>",1,globals->req); |
467 |
/* This is not elegant, but we want to avoid to print |
383 |
TclWeb_PrintError(errorinfo,0,globals->req); |
468 |
* this error message if an ErrorScript will handle this error. |
|
|
469 |
* Thus we print the usual error message only if we are running the |
470 |
* default error handler |
471 |
*/ |
472 |
|
473 |
if (conf->rivet_error_script == NULL) { |
474 |
|
475 |
Rivet_PrintErrorMessage(interp,"<b>Rivet AbortScript failed</b>"); |
476 |
} |
477 |
else |
478 |
{ |
479 |
result = Rivet_ExecuteErrorHandler(interp,conf->rivet_abort_script,req); |
480 |
} |
384 |
} |
481 |
} |
385 |
} |
482 |
} |
386 |
goto good; |
483 |
else |
|
|
484 |
{ |
485 |
|
486 |
/* If the script issued a ::rivet::abort_page but no AbortScript was |
487 |
* defined we return a TCL_OK anyway |
488 |
*/ |
489 |
|
490 |
result = TCL_OK; |
491 |
|
492 |
} |
387 |
} |
493 |
} |
388 |
} |
494 |
} |
|
|
495 |
else |
496 |
{ |
497 |
/* Invoke Rivet error handler */ |
389 |
|
498 |
|
390 |
Tcl_SetVar( interp, "errorOutbuf",Tcl_GetStringFromObj( tcl_script_obj, NULL ),TCL_GLOBAL_ONLY ); |
499 |
result = Rivet_ExecuteErrorHandler(interp,tcl_script_obj,req); |
391 |
|
500 |
|
392 |
/* If we don't have an error script, use the default error handler. */ |
|
|
393 |
if (conf->rivet_error_script) { |
394 |
errscript = conf->rivet_error_script; |
395 |
} else { |
396 |
errscript = conf->rivet_default_error_script; |
397 |
} |
501 |
} |
398 |
|
502 |
|
399 |
Tcl_IncrRefCount(errscript); |
|
|
400 |
if (Tcl_EvalObjEx(interp, errscript, 0) == TCL_ERROR) { |
401 |
CONST84 char *errorinfo = Tcl_GetVar( interp, "errorInfo", 0 ); |
402 |
TclWeb_PrintError("<b>Rivet ErrorScript failed!</b>",1,globals->req); |
403 |
TclWeb_PrintError( errorinfo, 0, globals->req ); |
404 |
} |
405 |
|
503 |
|
406 |
/* This shouldn't make the default_error_script go away, |
|
|
407 |
* because it gets a Tcl_IncrRefCount when it is created. */ |
408 |
Tcl_DecrRefCount(errscript); |
409 |
} |
504 |
} |
410 |
|
|
|
411 |
good: |
412 |
|
505 |
|
413 |
/* Tcl_Flush moved to the end of Rivet_SendContent */ |
506 |
/* Tcl_Flush moved to the end of Rivet_SendContent */ |
414 |
|
507 |
|
Lines 425-431
Link Here
|
425 |
* if a Tcl script. |
518 |
* if a Tcl script. |
426 |
* |
519 |
* |
427 |
* This is a separate function so that it may be called from command 'parse' |
520 |
* This is a separate function so that it may be called from command 'parse' |
|
|
521 |
* |
522 |
* Returned value: |
428 |
* |
523 |
* |
|
|
524 |
* - One of the Tcl defined values returned by Rivet_ExecuteAndCheck (TCL_OK, |
525 |
* TCL_ERROR, TCL_BREAK etc.) |
526 |
* |
429 |
* Arguments: |
527 |
* Arguments: |
430 |
* |
528 |
* |
431 |
* - TclWebRequest: pointer to the structure collecting Tcl and Apache data |
529 |
* - TclWebRequest: pointer to the structure collecting Tcl and Apache data |
Lines 434-439
Link Here
|
434 |
* - toplevel: integer to be interpreted as a boolean meaning the |
532 |
* - toplevel: integer to be interpreted as a boolean meaning the |
435 |
* file is pointed by the request. When 0 that's a subtemplate |
533 |
* file is pointed by the request. When 0 that's a subtemplate |
436 |
* to be parsed and executed from another template |
534 |
* to be parsed and executed from another template |
|
|
535 |
* |
437 |
*/ |
536 |
*/ |
438 |
|
537 |
|
439 |
int |
538 |
int |
Lines 443-449
Link Here
|
443 |
int isNew = 0; |
542 |
int isNew = 0; |
444 |
int result = 0; |
543 |
int result = 0; |
445 |
|
544 |
|
446 |
Tcl_Obj *outbuf = NULL; |
545 |
Tcl_Obj *outbuf = NULL; |
447 |
Tcl_HashEntry *entry = NULL; |
546 |
Tcl_HashEntry *entry = NULL; |
448 |
|
547 |
|
449 |
time_t ctime; |
548 |
time_t ctime; |
Lines 1477-1483
Link Here
|
1477 |
if (Rivet_ParseExecFile(globals->req, r->filename, 1) != TCL_OK) |
1576 |
if (Rivet_ParseExecFile(globals->req, r->filename, 1) != TCL_OK) |
1478 |
{ |
1577 |
{ |
1479 |
ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, r->server, |
1578 |
ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, r->server, |
1480 |
MODNAME ": Error parsing exec file '%s': %s", |
1579 |
MODNAME ": Error in Rivet_ParseExecFile exec file '%s': %s", |
1481 |
r->filename, |
1580 |
r->filename, |
1482 |
Tcl_GetVar(interp, "errorInfo", 0)); |
1581 |
Tcl_GetVar(interp, "errorInfo", 0)); |
1483 |
} |
1582 |
} |
Lines 1488-1496
Link Here
|
1488 |
{ |
1587 |
{ |
1489 |
if (Rivet_ExecuteAndCheck(interp, rsc->after_every_script,r) == TCL_ERROR) |
1588 |
if (Rivet_ExecuteAndCheck(interp, rsc->after_every_script,r) == TCL_ERROR) |
1490 |
{ |
1589 |
{ |
1491 |
CONST84 char *errorinfo = Tcl_GetVar( interp, "errorInfo", 0 ); |
1590 |
Rivet_PrintErrorMessage(interp,"<b>Rivet AfterEveryScript failed</b>"); |
1492 |
TclWeb_PrintError("<b>Rivet AfterEveryScript failed!</b>",1,globals->req); |
|
|
1493 |
TclWeb_PrintError( errorinfo, 0, globals->req ); |
1494 |
} |
1591 |
} |
1495 |
} |
1592 |
} |
1496 |
|
1593 |
|