mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-17 06:48:47 +02:00
Add $ExpressionTimeLimit system variable.
This commit is contained in:
@@ -1314,7 +1314,7 @@ int DoSatRemind(Trigger *trig, TimeTrig *tt, ParsePtr p)
|
||||
free_expr_tree(sat_node);
|
||||
return E_EXPIRED;
|
||||
}
|
||||
r = evaluate_expr_node(sat_node, NULL, &v, &nonconst);
|
||||
r = evaluate_expression(sat_node, NULL, &v, &nonconst);
|
||||
if (r) {
|
||||
free_expr_tree(sat_node);
|
||||
return r;
|
||||
|
||||
@@ -124,6 +124,7 @@
|
||||
#define E_EXPECTING_WEEKDAY 104
|
||||
#define E_REPEATED_ARG 105
|
||||
#define E_EXPR_DISABLED 106
|
||||
#define E_TIME_EXCEEDED 107
|
||||
|
||||
#ifdef MK_GLOBALS
|
||||
#undef EXTERN
|
||||
@@ -248,7 +249,8 @@ EXTERN char *ErrMsg[]
|
||||
/* E_DURATION_NO_AT */ "Cannot specify DURATION without specifying AT",
|
||||
/* E_EXPECTING_WEEKDAY */ "Expecting weekday name",
|
||||
/* E_REPEATED_ARG */ "Duplicate argument name",
|
||||
/* E_EXPR_DISABLED */ "Expression evaluation is disabled"
|
||||
/* E_EXPR_DISABLED */ "Expression evaluation is disabled",
|
||||
/* E_TIME_EXCEEDED */ "Time limit for expression evaluation exceeded",
|
||||
}
|
||||
#endif /* MK_GLOBALS */
|
||||
;
|
||||
|
||||
22
src/expr.c
22
src/expr.c
@@ -24,6 +24,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
The parser parses expressions into an internal tree
|
||||
@@ -662,6 +663,21 @@ eval_userfunc(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
evaluate_expression(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
{
|
||||
int r;
|
||||
|
||||
/* Set up time limits */
|
||||
if (ExpressionEvaluationTimeLimit > 0) {
|
||||
ExpressionTimeLimitExceeded = 0;
|
||||
alarm(ExpressionEvaluationTimeLimit);
|
||||
}
|
||||
r = evaluate_expr_node(node, locals, ans, nonconst);
|
||||
alarm(0);
|
||||
return r;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* evaluate_expr_node - the top-level expression evaluation */
|
||||
@@ -691,6 +707,10 @@ evaluate_expr_node(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
return E_EXPR_DISABLED;
|
||||
}
|
||||
|
||||
if (ExpressionTimeLimitExceeded) {
|
||||
ExpressionTimeLimitExceeded = 0;
|
||||
return E_TIME_EXCEEDED;
|
||||
}
|
||||
if (!node) {
|
||||
return E_SWERR;
|
||||
}
|
||||
@@ -2370,7 +2390,7 @@ int EvalExpr(char const **e, Value *v, ParsePtr p)
|
||||
}
|
||||
|
||||
/* Evaluate */
|
||||
r = evaluate_expr_node(n, NULL, v, &nonconst);
|
||||
r = evaluate_expression(n, NULL, v, &nonconst);
|
||||
|
||||
/* Throw away the parsed tree */
|
||||
free_expr_tree(n);
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#define INIT(var, val) var
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
@@ -74,6 +75,8 @@ EXTERN INIT( int DefaultTDelta, 0);
|
||||
EXTERN INIT( int DeltaOverride, 0);
|
||||
EXTERN INIT( int RunDisabled, 0);
|
||||
EXTERN INIT( int ExpressionEvaluationDisabled, 0);
|
||||
EXTERN INIT( int ExpressionEvaluationTimeLimit, 0);
|
||||
EXTERN INIT( volatile sig_atomic_t ExpressionTimeLimitExceeded, 0);
|
||||
EXTERN INIT( int IgnoreOnce, 0);
|
||||
EXTERN INIT( int SortByTime, 0);
|
||||
EXTERN INIT( int SortByDate, 0);
|
||||
|
||||
17
src/init.c
17
src/init.c
@@ -30,7 +30,6 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <termios.h>
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef HAVE_INITGROUPS
|
||||
#include <grp.h>
|
||||
@@ -1014,30 +1013,14 @@ AddTrustedUser(char const *username)
|
||||
TrustedUsers[NumTrustedUsers] = pwent->pw_uid;
|
||||
NumTrustedUsers++;
|
||||
}
|
||||
static void
|
||||
sigalarm(int)
|
||||
{
|
||||
write(STDOUT_FILENO, "\nExecution time exceeded.\n", 26);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void
|
||||
ProcessLongOption(char const *arg)
|
||||
{
|
||||
int t;
|
||||
if (!strcmp(arg, "version")) {
|
||||
printf("%s\n", VERSION);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
if (sscanf(arg, "max-execution-time=%d", &t) == 1) {
|
||||
if (t <= 0) {
|
||||
fprintf(ErrFp, "%s: Value of --max-execution-time must be positive\n", ArgV[0]);
|
||||
return;
|
||||
}
|
||||
signal(SIGALRM, sigalarm);
|
||||
alarm(t);
|
||||
return;
|
||||
}
|
||||
fprintf(ErrFp, "%s: Unknown long option --%s\n", ArgV[0], arg);
|
||||
}
|
||||
|
||||
|
||||
20
src/main.c
20
src/main.c
@@ -67,6 +67,13 @@ exitfunc(void)
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
static void sigalrm(int)
|
||||
{
|
||||
if (ExpressionEvaluationTimeLimit) {
|
||||
ExpressionTimeLimitExceeded = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/***************************************************************/
|
||||
/** **/
|
||||
@@ -78,6 +85,8 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
int pid;
|
||||
|
||||
struct sigaction act;
|
||||
|
||||
#ifdef HAVE_SETLOCALE
|
||||
setlocale(LC_ALL, "");
|
||||
#endif
|
||||
@@ -90,6 +99,15 @@ int main(int argc, char *argv[])
|
||||
ArgV = (char const **) argv;
|
||||
|
||||
InitRemind(argc, (char const **) argv);
|
||||
|
||||
act.sa_handler = sigalrm;
|
||||
sigemptyset(&act.sa_mask);
|
||||
if (sigaction(SIGALRM, &act, NULL) < 0) {
|
||||
fprintf(stderr, "%s: sigaction() failed: %s\n",
|
||||
argv[0], strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
DBufInit(&(LastTrigger.tags));
|
||||
ClearLastTriggers();
|
||||
|
||||
@@ -676,7 +694,7 @@ int EvaluateExpr(ParsePtr p, Value *v)
|
||||
return E_SWERR;
|
||||
}
|
||||
|
||||
r = evaluate_expr_node(node, NULL, v, &nonconst);
|
||||
r = evaluate_expression(node, NULL, v, &nonconst);
|
||||
free_expr_tree(node);
|
||||
if (r) return r;
|
||||
if (nonconst) {
|
||||
|
||||
@@ -59,6 +59,7 @@ int ParseLiteralDate (char const **s, int *dse, int *tim);
|
||||
int ParseLiteralTime (char const **s, int *tim);
|
||||
expr_node *parse_expression(char const **e, int *r, Var *locals);
|
||||
|
||||
int evaluate_expression(expr_node *node, Value *locals, Value *ans, int *nonconst);
|
||||
int evaluate_expr_node(expr_node *node, Value *locals, Value *ans, int *nonconst);
|
||||
void print_expr_tree(expr_node *node, FILE *fp);
|
||||
expr_node *free_expr_tree(expr_node *node);
|
||||
|
||||
@@ -310,6 +310,9 @@ void HandleQueuedReminders(void)
|
||||
struct sigaction sa;
|
||||
char qid[64];
|
||||
|
||||
/* Disable any potential pending SIGALRMs */
|
||||
alarm(0);
|
||||
|
||||
/* Turn off sorting -- otherwise, TriggerReminder has no effect! */
|
||||
SortByDate = 0;
|
||||
|
||||
|
||||
23
src/var.c
23
src/var.c
@@ -319,6 +319,28 @@ static int datetime_sep_func(int do_set, Value *val)
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int expr_time_limit_func(int do_set, Value *val)
|
||||
{
|
||||
if (!do_set) {
|
||||
val->type = INT_TYPE;
|
||||
val->v.val = ExpressionEvaluationTimeLimit;
|
||||
return OK;
|
||||
}
|
||||
if (val->type != INT_TYPE) return E_BAD_TYPE;
|
||||
if (val->v.val < 0) return E_2LOW;
|
||||
|
||||
if (!TopLevel()) {
|
||||
/* Ignore attempts to set from non-toplevel unless it's
|
||||
lower than current value */
|
||||
if (val->v.val <= ExpressionEvaluationTimeLimit) {
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
ExpressionEvaluationTimeLimit = val->v.val;
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int default_color_func(int do_set, Value *val)
|
||||
{
|
||||
int col_r, col_g, col_b;
|
||||
@@ -808,6 +830,7 @@ static SysVar SysVarArr[] = {
|
||||
{"DontTrigAts", 0, INT_TYPE, &DontIssueAts, 0, 0 },
|
||||
{"EndSent", 1, STR_TYPE, &EndSent, 0, 0 },
|
||||
{"EndSentIg", 1, STR_TYPE, &EndSentIg, 0, 0 },
|
||||
{"ExpressionTimeLimit", 1, SPECIAL_TYPE, expr_time_limit_func, 0, 0 },
|
||||
{"February", 1, STR_TYPE, &DynamicMonthName[1], 0, 0 },
|
||||
{"FirstIndent", 1, INT_TYPE, &FirstIndent, 0, 132 },
|
||||
{"FoldYear", 1, INT_TYPE, &FoldYear, 0, 1 },
|
||||
|
||||
Reference in New Issue
Block a user