~ubuntu-dev/ubuntu/lucid/zabbix/lucid-201002110857

« back to all changes in this revision

Viewing changes to frontends/php/include/triggers.inc.php

  • Committer: Bazaar Package Importer
  • Author(s): Michael Ablassmeier
  • Date: 2007-07-02 09:06:51 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070702090651-8l6fl3fjw9rh6l2u
Tags: 1:1.4.1-2
Add patch from SVN in order to fix Incorrect processing of character '%'
in user parameters and remote commands.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
**/
20
20
?>
21
21
<?php
 
22
        require_once "maps.inc.php";
 
23
        require_once "acknow.inc.php";
 
24
 
 
25
        /*
 
26
         * Function: INIT_TRIGGER_EXPRESSION_STRUCTURES
 
27
         *
 
28
         * Description: 
 
29
         *     initialize structures for trigger expression
 
30
         *     
 
31
         * Author: 
 
32
         *     Eugene Grigorjev (eugene.grigorjev@zabbix.com)
 
33
         *
 
34
         * Comments:
 
35
         *
 
36
         */
 
37
        function INIT_TRIGGER_EXPRESSION_STRUCTURES()
 
38
        {
 
39
                if ( defined('TRIGGER_EXPRESSION_STRUCTURES_OK') ) return;
 
40
                define('TRIGGER_EXPRESSION_STRUCTURES_OK', 1);
 
41
 
 
42
                global $ZBX_TR_EXPR_ALLOWED_MACROS, $ZBX_TR_EXPR_REPLACE_TO, $ZBX_TR_EXPR_ALLOWED_FUNCTIONS;
 
43
 
 
44
                $ZBX_TR_EXPR_ALLOWED_MACROS['{TRIGGER.VALUE}'] = '{TRIGGER.VALUE}';
 
45
 
 
46
                $ZBX_TR_EXPR_REPLACE_TO = 'zbx_expr_ok';
 
47
 
 
48
                $ZBX_TR_EXPR_ALLOWED_FUNCTIONS['abschange']     = array('args' => null,
 
49
                        'item_types' => array(
 
50
                                ITEM_VALUE_TYPE_FLOAT,
 
51
                                ITEM_VALUE_TYPE_UINT64,
 
52
                                ITEM_VALUE_TYPE_STR,
 
53
                                ITEM_VALUE_TYPE_TEXT
 
54
                                )
 
55
                        );
 
56
                $ZBX_TR_EXPR_ALLOWED_FUNCTIONS['avg']   = array('args' => array(        0 => array('type' => 'sec_num','mandat' => true) ),
 
57
                        'item_types' => array(
 
58
                                ITEM_VALUE_TYPE_FLOAT,
 
59
                                ITEM_VALUE_TYPE_UINT64
 
60
                                ),
 
61
                        );
 
62
                $ZBX_TR_EXPR_ALLOWED_FUNCTIONS['delta'] = array('args' => array( 0 => array('type' => 'sec_num','mandat' => true) ),
 
63
                        'item_types' => array(
 
64
                                ITEM_VALUE_TYPE_FLOAT,
 
65
                                ITEM_VALUE_TYPE_UINT64
 
66
                                ),
 
67
                        );
 
68
                $ZBX_TR_EXPR_ALLOWED_FUNCTIONS['change']        = array('args' => null,
 
69
                        'item_types' => array(
 
70
                                ITEM_VALUE_TYPE_FLOAT,
 
71
                                ITEM_VALUE_TYPE_UINT64,
 
72
                                ITEM_VALUE_TYPE_STR,
 
73
                                ITEM_VALUE_TYPE_TEXT
 
74
                                ),
 
75
                        );
 
76
                $ZBX_TR_EXPR_ALLOWED_FUNCTIONS['count'] = array('args' => array( 0 => array('type' => 'sec','mandat' => true), 1 => array('type' => 'str') ),
 
77
                        'item_types' => array(
 
78
                                ITEM_VALUE_TYPE_FLOAT,
 
79
                                ITEM_VALUE_TYPE_UINT64,
 
80
                                ITEM_VALUE_TYPE_LOG,
 
81
                                ITEM_VALUE_TYPE_STR,
 
82
                                ITEM_VALUE_TYPE_TEXT
 
83
                                )
 
84
                        );
 
85
                $ZBX_TR_EXPR_ALLOWED_FUNCTIONS['date']  = array('args' => null, 'item_types' => null );
 
86
 
 
87
                $ZBX_TR_EXPR_ALLOWED_FUNCTIONS['dayofweek']= array('args' => null,      'item_types' => null );
 
88
 
 
89
                $ZBX_TR_EXPR_ALLOWED_FUNCTIONS['diff']  = array('args' => null,
 
90
                        'item_types' => array(
 
91
                                ITEM_VALUE_TYPE_FLOAT,
 
92
                                ITEM_VALUE_TYPE_UINT64,
 
93
                                ITEM_VALUE_TYPE_STR,
 
94
                                ITEM_VALUE_TYPE_TEXT
 
95
                                )
 
96
                        );
 
97
                $ZBX_TR_EXPR_ALLOWED_FUNCTIONS['fuzzytime']     = array('args' => null,
 
98
                        'item_types' => array(
 
99
                                ITEM_VALUE_TYPE_FLOAT,
 
100
                                ITEM_VALUE_TYPE_UINT64
 
101
                                )
 
102
                        );
 
103
                $ZBX_TR_EXPR_ALLOWED_FUNCTIONS['last']  = array('args' => null,
 
104
                        'item_types' => array(
 
105
                                ITEM_VALUE_TYPE_FLOAT,
 
106
                                ITEM_VALUE_TYPE_UINT64,
 
107
                                ITEM_VALUE_TYPE_STR,
 
108
                                ITEM_VALUE_TYPE_TEXT
 
109
                                )
 
110
                        );
 
111
                $ZBX_TR_EXPR_ALLOWED_FUNCTIONS['max']   = array('args' => array( 0 => array('type' => 'sec_num','mandat' => true) ),
 
112
                        'item_types' => array(
 
113
                                ITEM_VALUE_TYPE_FLOAT,
 
114
                                ITEM_VALUE_TYPE_UINT64
 
115
                                )
 
116
                        );
 
117
                $ZBX_TR_EXPR_ALLOWED_FUNCTIONS['min']   = array('args' => array( 0 => array('type' => 'sec_num','mandat' => true) ),
 
118
                        'item_types' => array(
 
119
                                ITEM_VALUE_TYPE_FLOAT,
 
120
                                ITEM_VALUE_TYPE_UINT64
 
121
                                )
 
122
                        );
 
123
                $ZBX_TR_EXPR_ALLOWED_FUNCTIONS['nodata']= array('args' => array( 0 => array('type' => 'sec','mandat' => true) ), 'item_types' => null );
 
124
                $ZBX_TR_EXPR_ALLOWED_FUNCTIONS['now']   = array('args' => null, 'item_types' => null );
 
125
                $ZBX_TR_EXPR_ALLOWED_FUNCTIONS['prev']  = array('args' => null,
 
126
                        'item_types' => array(
 
127
                                ITEM_VALUE_TYPE_FLOAT,
 
128
                                ITEM_VALUE_TYPE_UINT64,
 
129
                                ITEM_VALUE_TYPE_STR,
 
130
                                ITEM_VALUE_TYPE_TEXT
 
131
                                )
 
132
                        );
 
133
                $ZBX_TR_EXPR_ALLOWED_FUNCTIONS['str']   = array('args' => array( 0 => array('type' => 'str','mandat' => true) ),
 
134
                        'item_types' => array(
 
135
                                ITEM_VALUE_TYPE_STR,
 
136
                                ITEM_VALUE_TYPE_LOG
 
137
                                )
 
138
                        );
 
139
 
 
140
 
 
141
                $ZBX_TR_EXPR_ALLOWED_FUNCTIONS['sum']   = array('args' => array( 0 => array('type' => 'sec_num','mandat' => true) ),
 
142
                        'item_types' => array(
 
143
                                ITEM_VALUE_TYPE_FLOAT,
 
144
                                ITEM_VALUE_TYPE_UINT64
 
145
                                )
 
146
                        );
 
147
                $ZBX_TR_EXPR_ALLOWED_FUNCTIONS['logseverity']= array('args' => null,
 
148
                        'item_types' => array(
 
149
                                ITEM_VALUE_TYPE_LOG
 
150
                                )
 
151
                        );
 
152
                $ZBX_TR_EXPR_ALLOWED_FUNCTIONS['logsource']= array('args' => array( 0=> array('type' => 'str','mandat' => true) ),
 
153
                        'item_types' => array(
 
154
                                ITEM_VALUE_TYPE_LOG
 
155
                                )
 
156
                        );
 
157
 
 
158
                $ZBX_TR_EXPR_ALLOWED_FUNCTIONS['regexp']= array('args' => array( 0 => array('type' => 'str','mandat' => true) ),
 
159
                        'item_types' => array(
 
160
                                ITEM_VALUE_TYPE_STR,
 
161
                                ITEM_VALUE_TYPE_LOG
 
162
                                )
 
163
                        );
 
164
        }
 
165
 
 
166
        INIT_TRIGGER_EXPRESSION_STRUCTURES();
 
167
 
 
168
 
 
169
        /*
 
170
         * Function: get_severity_style 
 
171
         *
 
172
         * Description: 
 
173
         *     convert severity constant in to the CSS style name
 
174
         *     
 
175
         * Author: 
 
176
         *     Eugene Grigorjev (eugene.grigorjev@zabbix.com)
 
177
         *
 
178
         * Comments:
 
179
         *
 
180
         */
 
181
        function        get_severity_style($severity)
 
182
        {
 
183
                if($severity == TRIGGER_SEVERITY_INFORMATION)   return 'information';
 
184
                elseif($severity == TRIGGER_SEVERITY_WARNING)   return 'warning';
 
185
                elseif($severity == TRIGGER_SEVERITY_AVERAGE)   return 'average';
 
186
                elseif($severity == TRIGGER_SEVERITY_HIGH)      return 'high';
 
187
                elseif($severity == TRIGGER_SEVERITY_DISASTER)  return 'disaster';
 
188
 
 
189
                return '';
 
190
        }
 
191
 
 
192
        /*
 
193
         * Function: get_severity_description 
 
194
         *
 
195
         * Description: 
 
196
         *     convert severity constant in to the string representation
 
197
         *     
 
198
         * Author: 
 
199
         *     Eugene Grigorjev (eugene.grigorjev@zabbix.com)
 
200
         *
 
201
         * Comments:
 
202
         *
 
203
         */
22
204
        function        get_severity_description($severity)
23
205
        {
24
 
                if($severity == 0)      return S_NOT_CLASSIFIED;
25
 
                else if($severity == 1) return S_INFORMATION;
26
 
                else if($severity == 2) return S_WARNING;
27
 
                else if($severity == 3) return S_AVERAGE;
28
 
                else if($severity == 4) return S_HIGH;
29
 
                else if($severity == 5) return S_DISASTER;
30
 
 
31
 
                return "Unknown";
32
 
        }
33
 
 
 
206
                if($severity == TRIGGER_SEVERITY_NOT_CLASSIFIED)        return S_NOT_CLASSIFIED;
 
207
                else if($severity == TRIGGER_SEVERITY_INFORMATION)      return S_INFORMATION;
 
208
                else if($severity == TRIGGER_SEVERITY_WARNING)          return S_WARNING;
 
209
                else if($severity == TRIGGER_SEVERITY_AVERAGE)          return S_AVERAGE;
 
210
                else if($severity == TRIGGER_SEVERITY_HIGH)             return S_HIGH;
 
211
                else if($severity == TRIGGER_SEVERITY_DISASTER)         return S_DISASTER;
 
212
 
 
213
                return S_UNKNOWN;
 
214
        }
 
215
 
 
216
        /*
 
217
         * Function: get_trigger_value_style 
 
218
         *
 
219
         * Description: 
 
220
         *     convert trigger value in to the CSS style name
 
221
         *     
 
222
         * Author: 
 
223
         *     Eugene Grigorjev (eugene.grigorjev@zabbix.com)
 
224
         *
 
225
         * Comments:
 
226
         *
 
227
         */
 
228
        function        get_trigger_value_style($value)
 
229
        {
 
230
                $str_val[TRIGGER_VALUE_FALSE]   = 'off';
 
231
                $str_val[TRIGGER_VALUE_TRUE]    = 'on';
 
232
                $str_val[TRIGGER_VALUE_UNKNOWN] = 'unknown';
 
233
 
 
234
                if(isset($str_val[$value]))
 
235
                        return $str_val[$value];
 
236
 
 
237
                return '';
 
238
        }
 
239
 
 
240
        /*
 
241
         * Function: trigger_value2str 
 
242
         *
 
243
         * Description: 
 
244
         *     convert trigger value in to the string representation
 
245
         *     
 
246
         * Author: 
 
247
         *     Eugene Grigorjev (eugene.grigorjev@zabbix.com)
 
248
         *
 
249
         * Comments:
 
250
         *
 
251
         */
 
252
        function        trigger_value2str($value)
 
253
        {
 
254
                $str_val[TRIGGER_VALUE_FALSE]   = S_FALSE_BIG;
 
255
                $str_val[TRIGGER_VALUE_TRUE]    = S_TRUE_BIG;
 
256
                $str_val[TRIGGER_VALUE_UNKNOWN] = S_UNKNOWN_BIG;
 
257
 
 
258
                if(isset($str_val[$value]))
 
259
                        return $str_val[$value];
 
260
 
 
261
                return S_UNKNOWN;
 
262
        }
 
263
 
 
264
        /*
 
265
         * Function: get_realhosts_by_triggerid 
 
266
         *
 
267
         * Description: 
 
268
         *     retrive real host for trigger
 
269
         *     
 
270
         * Author: 
 
271
         *     Eugene Grigorjev (eugene.grigorjev@zabbix.com)
 
272
         *
 
273
         * Comments:
 
274
         *
 
275
         */
34
276
        function        get_realhosts_by_triggerid($triggerid)
35
277
        {
36
278
                $trigger = get_trigger_by_triggerid($triggerid);
37
 
                if($trigger["templateid"] <> 0)
38
 
                        return get_realhosts_by_triggerid($trigger["templateid"]);
 
279
                if($trigger['templateid'] > 0)
 
280
                        return get_realhosts_by_triggerid($trigger['templateid']);
39
281
 
40
282
                return get_hosts_by_triggerid($triggerid);
41
283
        }
53
295
                return FALSE;
54
296
        }
55
297
 
56
 
        function        get_hosts_by_triggerid($triggerid)
57
 
        {
58
 
                return DBselect("select distinct h.* from hosts h, functions f, items i".
59
 
                        " where i.itemid=f.itemid and h.hostid=i.hostid and f.triggerid=$triggerid");
60
 
        }
61
 
 
62
 
        function        get_functions_by_triggerid($triggerid)
63
 
        {
64
 
                return DBselect("select * from functions where triggerid=$triggerid");
65
 
        }
66
 
 
67
 
        function        get_triggers_by_hostid($hostid, $show_mixed = "yes")
 
298
        function        &get_hosts_by_triggerid($triggerid)
 
299
        {
 
300
                return DBselect('select distinct h.* from hosts h, functions f, items i'.
 
301
                        ' where i.itemid=f.itemid and h.hostid=i.hostid and f.triggerid='.$triggerid);
 
302
        }
 
303
 
 
304
        function        &get_functions_by_triggerid($triggerid)
 
305
        {
 
306
                return DBselect('select * from functions where triggerid='.$triggerid);
 
307
        }
 
308
 
 
309
        /*
 
310
         * Function: get_triggers_by_hostid
 
311
         *
 
312
         * Description: 
 
313
         *     retrive selection of triggers by hostid
 
314
         *     
 
315
         * Author: 
 
316
         *     Eugene Grigorjev (eugene.grigorjev@zabbix.com)
 
317
         *
 
318
         * Comments:
 
319
         *
 
320
         */
 
321
        function        &get_triggers_by_hostid($hostid, $show_mixed = "yes")
68
322
        {
69
323
                $db_triggers = DBselect("select distinct t.* from triggers t, functions f, items i".
70
324
                        " where i.hostid=$hostid and f.itemid=i.itemid and f.triggerid=t.triggerid");
89
343
                return DBselect($sql);
90
344
        }
91
345
 
92
 
        function        get_triggers_by_templateid($triggerid)
93
 
        {
94
 
                        return DBselect("select * from triggers where templateid=$triggerid");
95
 
        }
96
 
 
97
 
        function        get_hosts_by_expression($expression)
98
 
        {
99
 
                $state="";
100
 
                $host="";
101
 
                $hosts=array();
102
 
                for($i=0,$max=strlen($expression); $i<$max; $i++)
103
 
                {
104
 
                        if($expression[$i] == '{' && $state=="")
105
 
                        {
106
 
                                $host="";
107
 
                                $state='HOST';
108
 
                                continue;
109
 
                        }
110
 
                        
111
 
                        if($expression[$i] == '}' && $state=="")
112
 
                        {
113
 
                                $state='';
114
 
                                $hosts[$host] = $host;
115
 
                                continue;
116
 
                        }
117
 
 
118
 
                        if($expression[$i] == '(' && $state == "FUNCTION")
119
 
                        {
120
 
                                $state='PARAMETER';
121
 
                                continue;
122
 
                        }
123
 
                        
124
 
                        if($expression[$i] == ')' && $state == "PARAMETER")
125
 
                        {
126
 
                                $state='';
127
 
                                continue;
128
 
                        }
129
 
                        
130
 
                        if($expression[$i] == ':' && $state == "HOST")
131
 
                        {
132
 
                                $state="KEY";
133
 
                                continue;
134
 
                        }
135
 
 
136
 
                        if($expression[$i] == '.' && ($state == "KEY" || $state == "FUNCTION"))
137
 
                        {
138
 
                                $state="FUNCTION";
139
 
                                continue;
140
 
                        }
141
 
 
142
 
                        if($state == "HOST")
143
 
                        {
144
 
                                $host .= $expression[$i];
145
 
                                continue;
146
 
                        }
147
 
                        if($state == "KEY" || $state == "FUNCTION" || $state == "PARAMETER")
148
 
                                continue;
149
 
                }
150
 
 
151
 
                $sql = "select distinct * from hosts where hostid=0";
152
 
                foreach($hosts as $host)
153
 
                {
154
 
                        $sql .= " or host=".zbx_dbstr($host);
155
 
                }
156
 
                return DBselect($sql);
157
 
        }
158
 
 
 
346
        function        &get_triggers_by_templateid($triggerid)
 
347
        {
 
348
                return DBselect('select * from triggers where templateid='.$triggerid);
 
349
        }
 
350
 
 
351
        /*
 
352
         * Function: get_hosts_by_expression
 
353
         *
 
354
         * Description: 
 
355
         *     retrive selection of hosts by trigger expression
 
356
         *     
 
357
         * Author: 
 
358
         *     Eugene Grigorjev (eugene.grigorjev@zabbix.com)
 
359
         *
 
360
         * Comments:
 
361
         *
 
362
         */
 
363
        function        &get_hosts_by_expression($expression)
 
364
        {
 
365
                global $ZBX_CURNODEID, $ZBX_TR_EXPR_ALLOWED_MACROS, $ZBX_TR_EXPR_REPLACE_TO;
 
366
 
 
367
                $expr = $expression;
 
368
 
 
369
                $hosts = array();
 
370
 
 
371
                /* Replace all {server:key.function(param)} and {MACRO} with '$ZBX_TR_EXPR_REPLACE_TO' */
 
372
                while(ereg(ZBX_EREG_EXPRESSION_TOKEN_FORMAT, $expr, $arr))
 
373
                {
 
374
                        if ( $arr[ZBX_EXPRESSION_MACRO_ID] && !isset($ZBX_TR_EXPR_ALLOWED_MACROS[$arr[ZBX_EXPRESSION_MACRO_ID]]) )
 
375
                        {
 
376
                                $hosts = array('0');
 
377
                                break;
 
378
                        }
 
379
                        else if( !$arr[ZBX_EXPRESSION_MACRO_ID] ) 
 
380
                        {
 
381
                                $hosts[] = zbx_dbstr($arr[ZBX_EXPRESSION_SIMPLE_EXPRESSION_ID + ZBX_SIMPLE_EXPRESSION_HOST_ID]);
 
382
                        }
 
383
                        $expr = $arr[ZBX_EXPRESSION_LEFT_ID].$ZBX_TR_EXPR_REPLACE_TO.$arr[ZBX_EXPRESSION_RIGHT_ID];
 
384
                }
 
385
 
 
386
                if(count($hosts) == 0) $hosts = array('0');
 
387
 
 
388
                return DBselect('select distinct * from hosts where '.DBid2nodeid('hostid').'='.$ZBX_CURNODEID.
 
389
                        ' and host in ('.implode(',',$hosts).')');
 
390
        }
 
391
 
 
392
        /*
 
393
         * Function: zbx_unquote_param
 
394
         *
 
395
         * Description: 
 
396
         *     unquote string and unescape cahrs
 
397
         *     
 
398
         * Author: 
 
399
         *     Eugene Grigorjev (eugene.grigorjev@zabbix.com)
 
400
         *
 
401
         * Comments:
 
402
         *     Double quotes used only.
 
403
         *     Unquote string only if value directly in quotes.
 
404
         *     Unescape only '\\' and '\"' combination
 
405
         *
 
406
         */
 
407
        function zbx_unquote_param($value)
 
408
        {
 
409
                $value = trim($value);
 
410
                if ( !empty($value) && '"' == $value[0] )
 
411
                { /* open quotes and unescape chars */
 
412
                        $value = substr($value, 1, strlen($value)-2);
 
413
 
 
414
                        $new_val = '';
 
415
                        for ( $i=0, $max=strlen($value); $i < $max; $i++)
 
416
                        {
 
417
                                if ( $i+1 < $max && $value[$i] == '\\' && ($value[$i+1] == '\\' || $value[$i+1] == '"') )
 
418
                                        $new_val .= $value[++$i];
 
419
                                else
 
420
                                        $new_val .= $value[$i];
 
421
                        }
 
422
                        $value = $new_val;
 
423
                }
 
424
                return $value;
 
425
        }
 
426
 
 
427
        /*
 
428
         * Function: zbx_get_params 
 
429
         *
 
430
         * Description: 
 
431
         *     parse list of quoted parameters
 
432
         *     
 
433
         * Author: 
 
434
         *     Eugene Grigorjev (eugene.grigorjev@zabbix.com)
 
435
         *
 
436
         * Comments:
 
437
         *     Double quotes used only.
 
438
         *
 
439
         */
 
440
        function zbx_get_params($string)
 
441
        {
 
442
                $params = array();
 
443
                $quoted = false;
 
444
 
 
445
                for( $param_s = $i = 0, $len = strlen($string); $i < $len; $i++)
 
446
                {
 
447
                        switch ( $string[$i] )
 
448
                        {
 
449
                                case '"':
 
450
                                        $quoted = !$quoted;
 
451
                                        break;
 
452
                                case ',':
 
453
                                        if ( !$quoted )
 
454
                                        {
 
455
                                                $params[] = zbx_unquote_param(substr($string, $param_s, $i - $param_s));
 
456
                                                $param_s = $i+1;
 
457
                                        }
 
458
                                        break;
 
459
                                case '\\':
 
460
                                        if ( $quoted && $i+1 < $len && ($string[$i+1] == '\\' || $string[$i+1] == '"'))
 
461
                                                $i++;
 
462
                                        break;
 
463
                        }
 
464
                }
 
465
 
 
466
                if( $quoted )
 
467
                {
 
468
                        error('Incorrect usage of quotes. ['.$string.']');
 
469
                        return null;
 
470
                }
 
471
 
 
472
                if( $i > $param_s )
 
473
                {
 
474
                        $params[] = zbx_unquote_param(substr($string, $param_s, $i - $param_s));
 
475
                }
 
476
 
 
477
                return $params;
 
478
        }
 
479
 
 
480
        /*
 
481
         * Function: validate_expression 
 
482
         *
 
483
         * Description: 
 
484
         *     check trigger expression syntax and validate values
 
485
         *     
 
486
         * Author: 
 
487
         *     Eugene Grigorjev (eugene.grigorjev@zabbix.com)
 
488
         *
 
489
         * Comments:
 
490
         *
 
491
         */
159
492
        function        validate_expression($expression)
160
493
        {
161
 
//              echo "Validating expression: $expression<br>";
162
 
                $exp_hosts = get_hosts_by_expression($expression);
163
 
 
164
 
                $ok=0;
165
 
// Replace all {server:key.function(param)} with 0
166
 
                while($ok==0)
167
 
                {
168
 
//                      echo "Expression:$expression<br>";
169
 
                        $arr="";
170
 
                        if (eregi('^((.)*)[ ]*(\{((.)*)\})[ ]*((.)*)$', $expression, $arr)) 
171
 
                        {
172
 
//                              for($i=0;$i<20;$i++)
173
 
//                              {
174
 
//                                      if($arr[$i])
175
 
//                                              echo "  $i: ",$arr[$i],"<br>";
176
 
//                              }
177
 
                                if(validate_simple_expression($arr[3])!=0)
178
 
                                {
179
 
                                        return -1;
180
 
                                }
181
 
                                $expression=$arr[1]."0".$arr[6];
182
 
                        }
183
 
                        else
184
 
                        {
185
 
                                $ok=1;
186
 
                        }
187
 
                }
188
 
//              echo "Result:$expression<br><hr>";
189
 
 
190
 
                $ok=0;
191
 
                while($ok==0)
192
 
                {
193
 
//      Replace all <float> <sign> <float> <K|M|G> with 0
194
 
//                      echo "Expression:$expression<br>";
195
 
                        $arr="";
196
 
// The '-' must be the last character in the list, otherwise it won't work!
197
 
                        if (eregi('^((.)*)([0-9\.]+[A-Z]{0,1})[ ]*([\&\|\>\<\=\+\*\/\#-]{1})[ ]*([0-9\.]+[A-Z]{0,1})((.)*)$', $expression, $arr)) 
198
 
                        {
199
 
//                              echo "OK<br>";
200
 
//                              for($i=0;$i<50;$i++)
201
 
//                              {
202
 
//                                      if($arr[$i]!="")
203
 
//                                              echo "  $i: ",$arr[$i],"<br>";
204
 
//                              }
205
 
                                if(validate_float($arr[3])!=0)
206
 
                                {
207
 
                                        error("[".$arr[3]."] is not a float");
208
 
                                        return -1;
209
 
                                }
210
 
                                if(validate_float($arr[5])!=0)
211
 
                                {
212
 
                                        error("[".$arr[5]."] is not a float");
213
 
                                        return -1;
214
 
                                }
215
 
                                $expression=$arr[1]."(0)".$arr[6];
216
 
                        }
217
 
                        else
218
 
                        {
219
 
                                $ok=1;
220
 
                        }
221
 
 
222
 
 
223
 
//      Replace all (float) with 0
224
 
//                      echo "Expression2:[$expression]<br>";
225
 
                        $arr="";
226
 
                        if (eregi('^((.)*)(\(([ 0-9\.]+)\))((.)*)$', $expression, $arr)) 
227
 
                        {
228
 
//                              echo "OK<br>";
229
 
//                              for($i=0;$i<30;$i++)
230
 
//                              {
231
 
//                                      if($arr[$i]!="")
232
 
//                                              echo "  $i: ",$arr[$i],"<br>";
233
 
//                              }
234
 
                                if(validate_float($arr[4])!=0)
235
 
                                {
236
 
                                        error("[".$arr[4]."] is not a float");
237
 
                                        return -1;
238
 
                                }
239
 
                                $expression=$arr[1]."0".$arr[5];
240
 
                                $ok=0;
241
 
                        }
242
 
                        else
243
 
                        {
244
 
                                $ok=1;
245
 
                        }
246
 
 
247
 
 
248
 
 
249
 
                }
250
 
 
251
 
                $exp_host = DBfetch($exp_hosts);
252
 
                if(!$exp_host)
253
 
                {
254
 
                        error("Incorrect trigger expression. Incorrect host is used.");
255
 
                        return 1;
256
 
                }
257
 
                else
258
 
                {
259
 
                        $rows=0;
260
 
                        unset($fail);
261
 
                        do
262
 
                        {
263
 
                                if($exp_host["status"]==HOST_STATUS_TEMPLATE)
264
 
                                {
265
 
                                        $fail=1;
266
 
                                }
267
 
                                $rows++;
268
 
                        } while($exp_host = DBfetch($exp_hosts));
269
 
 
270
 
                        if(isset($fail) && ($rows>1))
271
 
                        {
272
 
                                error("Incorrect trigger expression. You can't use template hosts".
273
 
                                        " in mixed expressions.");
274
 
                                return 1;
275
 
                        }
276
 
                }
277
 
 
278
 
                if($expression=="0")
279
 
                {
280
 
                        return 0;
281
 
                }
282
 
 
283
 
                error("Incorrect trigger expression '$expression'");
284
 
                return 1;
 
494
                global $ZBX_CURNODEID, $ZBX_TR_EXPR_ALLOWED_MACROS, $ZBX_TR_EXPR_REPLACE_TO, $ZBX_TR_EXPR_ALLOWED_FUNCTIONS;
 
495
 
 
496
                if( empty($expression) )
 
497
                {
 
498
                        error('Expression can\'t be empty');
 
499
                }
 
500
                
 
501
                $expr = $expression;
 
502
                $h_status = array();
 
503
 
 
504
                /* Replace all {server:key.function(param)} and {MACRO} with '$ZBX_TR_EXPR_REPLACE_TO' */
 
505
                while(ereg(ZBX_EREG_EXPRESSION_TOKEN_FORMAT, $expr, $arr))
 
506
                {
 
507
                        if ( $arr[ZBX_EXPRESSION_MACRO_ID] && !isset($ZBX_TR_EXPR_ALLOWED_MACROS[$arr[ZBX_EXPRESSION_MACRO_ID]]) )
 
508
                        {
 
509
                                error('Unknown macro ['.$arr[ZBX_EXPRESSION_MACRO_ID].']');
 
510
                                return false;
 
511
                        }
 
512
                        else if( !$arr[ZBX_EXPRESSION_MACRO_ID] ) 
 
513
                        {
 
514
                                $host           = &$arr[ZBX_EXPRESSION_SIMPLE_EXPRESSION_ID + ZBX_SIMPLE_EXPRESSION_HOST_ID];
 
515
                                $key            = &$arr[ZBX_EXPRESSION_SIMPLE_EXPRESSION_ID + ZBX_SIMPLE_EXPRESSION_KEY_ID];
 
516
                                $function       = &$arr[ZBX_EXPRESSION_SIMPLE_EXPRESSION_ID + ZBX_SIMPLE_EXPRESSION_FUNCTION_NAME_ID];
 
517
                                $parameter      = &$arr[ZBX_EXPRESSION_SIMPLE_EXPRESSION_ID + ZBX_SIMPLE_EXPRESSION_FUNCTION_PARAM_ID];
 
518
                                
 
519
                                /* Check host */
 
520
                                $row=DBfetch(DBselect('select count(*) as cnt,min(status) as status,min(hostid) as hostid from hosts h where h.host='.zbx_dbstr($host).
 
521
                                                ' and '.DBid2nodeid('h.hostid').'='.$ZBX_CURNODEID
 
522
                                        ));
 
523
                                if($row['cnt']==0)
 
524
                                {
 
525
                                        error('No such host ('.$host.')');
 
526
                                        return false;
 
527
                                }
 
528
                                elseif($row['cnt']!=1)
 
529
                                {
 
530
                                        error('Too many hosts ('.$host.')');
 
531
                                        return false;
 
532
                                }
 
533
 
 
534
                                $h_status[$row['status']][$row['hostid']] = $row['cnt'];
 
535
 
 
536
                                /* Check key */
 
537
                                if ( !($item = DBfetch(DBselect('select i.itemid,i.value_type from hosts h,items i where h.host='.zbx_dbstr($host).
 
538
                                                ' and i.key_='.zbx_dbstr($key).' and h.hostid=i.hostid '.
 
539
                                                ' and '.DBid2nodeid('h.hostid').'='.$ZBX_CURNODEID
 
540
                                        ))) )
 
541
                                {
 
542
                                        error('No such monitored parameter ('.$key.') for host ('.$host.')');
 
543
                                        return false;
 
544
                                }
 
545
 
 
546
                                /* Check function */
 
547
                                if( !isset($ZBX_TR_EXPR_ALLOWED_FUNCTIONS[$function]) )
 
548
                                {
 
549
                                        error('Unknown function ['.$function.']');
 
550
                                        return false;
 
551
                                }
 
552
 
 
553
                                $fnc_valid = &$ZBX_TR_EXPR_ALLOWED_FUNCTIONS[$function];
 
554
 
 
555
                                if ( is_array($fnc_valid['item_types']) &&
 
556
                                        !in_array($item['value_type'], $fnc_valid['item_types']))
 
557
                                {
 
558
                                        $allowed_types = array();
 
559
                                        foreach($fnc_valid['item_types'] as $type)
 
560
                                                $allowed_types[] = item_value_type2str($type);
 
561
                                        info('Function ('.$function.') available only for items with value types ['.implode(',',$allowed_types).']');
 
562
                                        error('Incorrect value type ['.item_value_type2str($item['value_type']).'] for function ('.$function.') of key ('.$host.':'.$key.')');
 
563
                                        return false;
 
564
                                }
 
565
 
 
566
                                if( !is_null($fnc_valid['args']) )
 
567
                                {
 
568
                                        $parameter = zbx_get_params($parameter);
 
569
 
 
570
                                        if( !is_array($fnc_valid['args']) )
 
571
                                                $fnc_valid['args'] = array($fnc_valid['args']);
 
572
 
 
573
                                        foreach($fnc_valid['args'] as $pid => $params)
 
574
                                        {
 
575
                                                if(!isset($parameter[$pid]))
 
576
                                                {
 
577
                                                        if( !isset($params['mandat']) ) 
 
578
                                                        {
 
579
                                                                continue;
 
580
                                                        }
 
581
                                                        else 
 
582
                                                        {
 
583
                                                                error('Missed mandatory parameter for function ('.$function.')');
 
584
                                                                return false;
 
585
                                                        }
 
586
                                                }
 
587
 
 
588
                                                if( 'sec' == $params['type'] 
 
589
                                                        && (validate_float($parameter[$pid])!=0) )
 
590
                                                {
 
591
                                                        error('['.$parameter[$pid].'] is not a float for function ('.$function.')');
 
592
                                                        return false;
 
593
                                                }
 
594
 
 
595
                                                if( 'sec_num' == $params['type'] 
 
596
                                                        && (validate_ticks($parameter[$pid])!=0) )
 
597
                                                {
 
598
                                                        error('['.$parameter[$pid].'] is not a float or counter for function ('.$function.')');
 
599
                                                        return false;
 
600
                                                }
 
601
                                        }
 
602
                                }
 
603
                        }
 
604
                        $expr = $arr[ZBX_EXPRESSION_LEFT_ID].$ZBX_TR_EXPR_REPLACE_TO.$arr[ZBX_EXPRESSION_RIGHT_ID];
 
605
                }
 
606
 
 
607
                if ( isset($h_status[HOST_STATUS_TEMPLATE]) && ( count($h_status) > 1 || count($h_status[HOST_STATUS_TEMPLATE]) > 1 ))
 
608
                {
 
609
                        error("Incorrect trigger expression. You can't use template hosts".
 
610
                                " in mixed expressions.");
 
611
                        return false;
 
612
                }
 
613
 
 
614
                /* Replace all calculations and numbers with '$ZBX_TR_EXPR_REPLACE_TO' */
 
615
                $expt_number = '('.$ZBX_TR_EXPR_REPLACE_TO.'|'.ZBX_EREG_NUMBER.')';
 
616
                $expt_term = '((\('.$expt_number.'\))|('.$expt_number.'))';
 
617
                $expr_format = '(('.$expt_term.ZBX_EREG_SIGN.$expt_term.')|(\('.$expt_term.'\)))';
 
618
                $expr_full_format = '((\('.$expr_format.'\))|('.$expr_format.'))';
 
619
 
 
620
                while($res = ereg($expr_full_format.'([[:print:]]*)$', $expr, $arr))
 
621
                {
 
622
                        $expr = substr($expr, 0, strpos($expr, $arr[1])).$ZBX_TR_EXPR_REPLACE_TO.$arr[54];
 
623
                }
 
624
 
 
625
                if ( $ZBX_TR_EXPR_REPLACE_TO != $expr )
 
626
                {
 
627
                        error('Incorrect trigger expression. ['.str_replace($ZBX_TR_EXPR_REPLACE_TO, ' ... ', $expr).']');
 
628
                        return false;
 
629
                }
 
630
 
 
631
                return true;
285
632
        }
286
633
 
287
634
 
289
636
                $expression, $description, $priority, $status,
290
637
                $comments, $url, $deps=array(), $templateid=0)
291
638
        {
292
 
//              if(!check_right("Trigger","A",0))
293
 
//              {
294
 
//                      error("Insufficient permissions");
295
 
//                      return  0;
296
 
//              }
297
 
                if(!is_null($expression)) if(validate_expression($expression))  return FALSE;
 
639
                if( !validate_expression($expression) )
 
640
                        return false;
 
641
 
 
642
                $triggerid=get_dbid("triggers","triggerid");
298
643
 
299
644
                $result=DBexecute("insert into triggers".
300
 
                        "  (description,priority,status,comments,url,value,error,templateid)".
301
 
                        " values (".zbx_dbstr($description).",$priority,$status,".zbx_dbstr($comments).",".
 
645
                        "  (triggerid,description,priority,status,comments,url,value,error,templateid)".
 
646
                        " values ($triggerid,".zbx_dbstr($description).",$priority,$status,".zbx_dbstr($comments).",".
302
647
                        "".zbx_dbstr($url).",2,'Trigger just added. No status update so far.',$templateid)");
303
648
                if(!$result)
304
649
                {
305
650
                        return  $result;
306
651
                }
307
652
 
308
 
                $triggerid = DBinsert_id($result,"triggers","triggerid");
309
 
                add_alarm($triggerid,TRIGGER_VALUE_UNKNOWN);
 
653
                add_event($triggerid,TRIGGER_VALUE_UNKNOWN);
310
654
 
311
 
                $expression = implode_exp($expression,$triggerid);
312
 
 
313
 
                DBexecute("update triggers set expression=".zbx_dbstr($expression)." where triggerid=$triggerid");
314
 
 
315
 
                reset_items_nextcheck($triggerid);
316
 
 
317
 
                foreach($deps as $val)
318
 
                {
319
 
                        $result = add_trigger_dependency($triggerid, $val);
 
655
                if( null == ($expression = implode_exp($expression,$triggerid)) )
 
656
                {
 
657
                        $result = false;
 
658
                }
 
659
 
 
660
                if($result)
 
661
                {
 
662
                        DBexecute("update triggers set expression=".zbx_dbstr($expression)." where triggerid=$triggerid");
 
663
 
 
664
                        reset_items_nextcheck($triggerid);
 
665
 
 
666
                        foreach($deps as $val)
 
667
                        {
 
668
                                $result = add_trigger_dependency($triggerid, $val);
 
669
                        }
320
670
                }
321
671
 
322
672
                $trig_hosts = get_hosts_by_triggerid($triggerid);
332
682
                }
333
683
 
334
684
                if($trig_host)
335
 
                {
 
685
                {// create trigger for childs
336
686
                        $child_hosts = get_hosts_by_templateid($trig_host["hostid"]);
337
687
                        while($child_host = DBfetch($child_hosts))
338
688
                        {
339
 
                                $result = copy_trigger_to_host($triggerid, $child_host["hostid"]);
340
 
                                if(!$result){
341
 
                                        if($templateid == 0)
342
 
                                        { // delete main trigger (and recursively childs)
343
 
                                                delete_trigger($triggerid);
344
 
                                        }
345
 
                                        return $result;
346
 
                                }
347
 
                        }
 
689
                                if( !($result = copy_trigger_to_host($triggerid, $child_host["hostid"])))
 
690
                                        break;
 
691
                        }
 
692
                }
 
693
 
 
694
                if(!$result){
 
695
                        if($templateid == 0)
 
696
                        { // delete main trigger (and recursively childs)
 
697
                                delete_trigger($triggerid);
 
698
                        }
 
699
                        return $result;
348
700
                }
349
701
 
350
702
                return $triggerid;
351
703
        }
352
704
 
353
 
        function        copy_trigger_to_host($triggerid, $hostid)
 
705
        /******************************************************************************
 
706
         *                                                                            *
 
707
         * Comments: !!! Don't forget sync code with C !!!                            *
 
708
         *                                                                            *
 
709
         ******************************************************************************/
 
710
        function        get_trigger_dependences_by_triggerid($triggerid)
 
711
        {
 
712
                $result = array();
 
713
 
 
714
                $db_deps = DBselect("select * from trigger_depends where triggerid_down=".$triggerid);
 
715
                while($db_dep = DBfetch($db_deps))
 
716
                                $result[] = $db_dep['triggerid_up'];
 
717
                        
 
718
                return $result;
 
719
        }
 
720
 
 
721
        /******************************************************************************
 
722
         *                                                                            *
 
723
         * Comments: !!! Don't forget sync code with C !!!                            *
 
724
         *                                                                            *
 
725
         ******************************************************************************/
 
726
        function        replace_template_dependences($deps, $hostid)
 
727
        {
 
728
                foreach($deps as $id => $val)
 
729
                {
 
730
                        if($db_new_dep = DBfetch(DBselect('select t.triggerid from triggers t,functions f,items i '.
 
731
                                ' where t.templateid='.$val.' and f.triggerid=t.triggerid '.
 
732
                                ' and f.itemid=i.itemid and i.hostid='.$hostid)))
 
733
                                        $deps[$id] = $db_new_dep['triggerid'];
 
734
                }
 
735
                return $deps;
 
736
        }
 
737
 
 
738
        /******************************************************************************
 
739
         *                                                                            *
 
740
         * Comments: !!! Don't forget sync code with C !!!                            *
 
741
         *                                                                            *
 
742
         ******************************************************************************/
 
743
        function        copy_trigger_to_host($triggerid, $hostid, $copy_mode = false)
354
744
        {
355
745
                $trigger = get_trigger_by_triggerid($triggerid);
356
746
 
357
 
                $deps = array();
358
 
                $db_deps = DBexecute("select * from trigger_depends where triggerid_down=".$triggerid);
359
 
                while($db_dep = DBfetch($db_deps))
360
 
                        array_push($deps, $db_dep["triggerid_up"]);
 
747
                $deps = replace_template_dependences(
 
748
                                get_trigger_dependences_by_triggerid($triggerid),
 
749
                                $hostid);
361
750
 
362
751
                $host_triggers = get_triggers_by_hostid($hostid, "no");
363
752
                while($host_trigger = DBfetch($host_triggers))
375
764
                                $trigger["comments"],
376
765
                                $trigger["url"],
377
766
                                $deps,
378
 
                                $triggerid);
 
767
                                $copy_mode ? 0 : $triggerid);
379
768
                }
380
769
 
 
770
                $newtriggerid=get_dbid("triggers","triggerid");
 
771
 
381
772
                $result = DBexecute("insert into triggers".
382
 
                        " (description,priority,status,comments,url,value,expression,templateid)".
383
 
                        " values (".zbx_dbstr($trigger["description"]).",".$trigger["priority"].","
384
 
                        .$trigger["status"].",".zbx_dbstr($trigger["comments"]).",".
385
 
                        zbx_dbstr($trigger["url"]).",2,'{???:???}', $triggerid)");
 
773
                        " (triggerid,description,priority,status,comments,url,value,expression,templateid)".
 
774
                        " values ($newtriggerid,".zbx_dbstr($trigger["description"]).",".$trigger["priority"].",".
 
775
                        $trigger["status"].",".zbx_dbstr($trigger["comments"]).",".
 
776
                        zbx_dbstr($trigger["url"]).",2,'{???:???}',".
 
777
                        ($copy_mode ? 0 : $triggerid).")");
386
778
 
387
779
                if(!$result)
388
780
                        return $result;
389
781
 
390
 
                $newtriggerid = DBinsert_id($result,"triggers","triggerid");
391
 
 
392
782
                $host = get_host_by_hostid($hostid);
393
783
                $newexpression = $trigger["expression"];
394
784
 
408
798
                                return FALSE;
409
799
                        }
410
800
 
411
 
                        $result = DBexecute("insert into functions (itemid,triggerid,function,parameter)".
412
 
                                " values (".$host_item["itemid"].",$newtriggerid,".
 
801
                        $newfunctionid=get_dbid("functions","functionid");
 
802
 
 
803
                        $result = DBexecute("insert into functions (functionid,itemid,triggerid,function,parameter)".
 
804
                                " values ($newfunctionid,".$host_item["itemid"].",$newtriggerid,".
413
805
                                zbx_dbstr($function["function"]).",".zbx_dbstr($function["parameter"]).")");
414
 
                        $newfunctionid = DBinsert_id($result,"functions","functionid");
415
806
 
416
807
                        $newexpression = str_replace(
417
808
                                "{".$function["functionid"]."}",
423
814
                        " where triggerid=$newtriggerid");
424
815
// copy dependences
425
816
                delete_dependencies_by_triggerid($newtriggerid);
426
 
                $db_deps = DBexecute("select * from trigger_depends where".
427
 
                        " triggerid_down=".$triggerid);
428
 
                while($db_dep = DBfetch($db_deps))
 
817
                foreach($deps as $dep_id)
429
818
                {
430
 
                        add_trigger_dependency($newtriggerid, $db_dep["triggerid_up"]);
 
819
                        add_trigger_dependency($newtriggerid, $dep_id);
431
820
                }
432
821
 
433
822
                info("Added trigger '".$trigger["description"]."' to host '".$host["host"]."'");
434
823
 
 
824
// Copy triggers to the child hosts
435
825
                $child_hosts = get_hosts_by_templateid($hostid);
436
826
                while($child_host = DBfetch($child_hosts))
437
827
                {// recursion
438
 
                        $result = copy_trigger_to_host($triggerid, $child_host["hostid"]);
 
828
                        $result = copy_trigger_to_host($newtriggerid, $child_host["hostid"]);
439
829
                        if(!$result){
440
830
                                return result;
441
831
                        }
444
834
                return $newtriggerid;
445
835
        }
446
836
        
447
 
        # Translate {10}>10 to something like localhost:procload.last(0)>10
448
837
 
449
 
        function        explode_exp ($expression, $html)
 
838
        /******************************************************************************
 
839
         *                                                                            *
 
840
         * Purpose: Translate {10}>10 to something like localhost:procload.last(0)>10 *
 
841
         *                                                                            *
 
842
         * Comments: !!! Don't forget sync code with C !!!                            *
 
843
         *                                                                            *
 
844
         ******************************************************************************/
 
845
        function        explode_exp ($expression, $html,$template=false)
450
846
        {
451
847
#               echo "EXPRESSION:",$expression,"<Br>";
452
848
 
464
860
                        if($expression[$i] == '}')
465
861
                        {
466
862
                                $state='';
467
 
                                $sql="select h.host,i.key_,f.function,f.parameter,i.itemid from items i,functions f,hosts h where functionid=$functionid and i.itemid=f.itemid and h.hostid=i.hostid";
468
 
                                $res1=DBselect($sql);
469
 
                                $row1=DBfetch($res1);
470
 
                                if($html == 0)
 
863
                                if($functionid=="TRIGGER.VALUE")
471
864
                                {
472
 
                                        $exp=$exp."{".$row1["host"].":".$row1["key_"].".".$row1["function"]."(".$row1["parameter"].")}";
 
865
                                        $exp .= "{".$functionid."}";
473
866
                                }
474
 
                                else
 
867
                                else if(is_numeric($functionid) && $function_data = DBfetch(DBselect('select h.host,i.key_,f.function,f.parameter,i.itemid,i.value_type'.
 
868
                                        ' from items i,functions f,hosts h'.
 
869
                                        ' where f.functionid='.$functionid.' and i.itemid=f.itemid and h.hostid=i.hostid')))
475
870
                                {
476
 
                                        $item=get_item_by_itemid($row1["itemid"]);
477
 
                                        if($item["value_type"] ==0) 
 
871
                                        if($template) $function_data["host"] = '{HOSTNAME}';
 
872
                                                
 
873
                                        if($html == 0)
478
874
                                        {
479
 
                                                $exp=$exp."{<A HREF=\"history.php?action=showgraph&itemid=".$row1["itemid"]."\">".$row1["host"].":".$row1["key_"]."</A>.<B>".$row1["function"]."(</B>".$row1["parameter"]."<B>)</B>}";
 
875
                                                $exp .= "{".$function_data["host"].":".$function_data["key_"].".".
 
876
                                                        $function_data["function"]."(".$function_data["parameter"].")}";
480
877
                                        }
481
878
                                        else
482
879
                                        {
483
 
                                                $exp=$exp."{<A HREF=\"history.php?action=showvalues&period=3600&itemid=".$row1["itemid"]."\">".$row1["host"].":".$row1["key_"]."</A>.<B>".$row1["function"]."(</B>".$row1["parameter"]."<B>)</B>}";
 
880
                                                $link = new CLink($function_data["host"].":".$function_data["key_"],
 
881
                                                        'history.php?action='.( $function_data["value_type"] ==0 ? 'showvalues' : 'showgraph').
 
882
                                                        '&itemid='.$function_data['itemid']);
 
883
                                        
 
884
                                                $exp .= $link->ToString().'.'.bold($function_data["function"].'(').$function_data["parameter"].bold(')');
484
885
                                        }
485
886
                                }
 
887
                                else
 
888
                                {
 
889
                                        if($html == 1)  $exp .= "<FONT COLOR=\"#AA0000\">";
 
890
                                        $exp .= "*ERROR*";
 
891
                                        if($html == 1)  $exp .= "</FONT>";
 
892
                                }
486
893
                                continue;
487
894
                        }
488
895
                        if($state == "FUNCTIONID")
496
903
                return $exp;
497
904
        }
498
905
 
 
906
        /*
 
907
         * Function: implode_exp
 
908
         *
 
909
         * Description: 
 
910
         *     Translate localhost:procload.last(0)>10 to {12}>10
 
911
         *     And create database representation.
 
912
         *     
 
913
         * Author: 
 
914
         *     Eugene Grigorjev (eugene.grigorjev@zabbix.com)
 
915
         *
 
916
         * Comments: !!! Don't forget sync code with C !!!
 
917
         *
 
918
         */
499
919
        function        implode_exp ($expression, $triggerid)
500
 
        # Translate localhost:procload.last(0)>10 to {12}>10
501
920
        {
502
 
//              echo "Expression:$expression<br>";
503
 
                $exp='';
504
 
                $state="";
505
 
                for($i=0,$max=strlen($expression); $i<$max; $i++)
 
921
                global $ZBX_TR_EXPR_ALLOWED_MACROS, $ZBX_TR_EXPR_REPLACE_TO;
 
922
                $expr = $expression;
 
923
                $short_exp = $expression;
 
924
 
 
925
                /* Replace all {server:key.function(param)} and {MACRO} with '$ZBX_TR_EXPR_REPLACE_TO' */
 
926
                /* build short expression {12}>10 */
 
927
                while(ereg(ZBX_EREG_EXPRESSION_TOKEN_FORMAT, $expr, $arr))
506
928
                {
507
 
                        if($expression[$i] == '{')
508
 
                        {
509
 
                                if($state=="")
510
 
                                {
511
 
                                        $host='';
512
 
                                        $key='';
513
 
                                        $function='';
514
 
                                        $parameter='';
515
 
                                        $state='HOST';
516
 
                                        continue;
517
 
                                }
518
 
                        }
519
 
                        if( ($expression[$i] == '}')&&($state=="") )
520
 
                        {
521
 
//                              echo "HOST:$host<BR>";
522
 
//                              echo "KEY:$key<BR>";
523
 
//                              echo "FUNCTION:$function<BR>";
524
 
//                              echo "PARAMETER:$parameter<BR>";
525
 
                                $state='';
526
 
                
527
 
                                $res=DBselect("select i.itemid from items i,hosts h".
528
 
                                        " where i.key_=".zbx_dbstr($key).
529
 
                                        " and h.host=".zbx_dbstr($host).
530
 
                                        " and h.hostid=i.hostid");
531
 
                                $row=DBfetch($res);
532
 
 
533
 
                                $itemid=$row["itemid"];
534
 
        
535
 
                                $res=DBexecute("insert into functions (itemid,triggerid,function,parameter)".
536
 
                                        " values ($itemid,$triggerid,".zbx_dbstr($function).",".
537
 
                                        zbx_dbstr($parameter).")");
538
 
                                if(!$res)
539
 
                                {
540
 
                                        return  $res;
541
 
                                }
542
 
                                $functionid=DBinsert_id($res,"functions","functionid");
543
 
 
544
 
                                $exp=$exp.'{'.$functionid.'}';
545
 
 
546
 
                                continue;
547
 
                        }
548
 
                        if($expression[$i] == '(')
549
 
                        {
550
 
                                if($state == "FUNCTION")
551
 
                                {
552
 
                                        $state='PARAMETER';
553
 
                                        continue;
554
 
                                }
555
 
                        }
556
 
                        if($expression[$i] == ')')
557
 
                        {
558
 
                                if($state == "PARAMETER")
559
 
                                {
560
 
                                        $state='';
561
 
                                        continue;
562
 
                                }
563
 
                        }
564
 
                        if(($expression[$i] == ':') && ($state == "HOST"))
565
 
                        {
566
 
                                $state="KEY";
567
 
                                continue;
568
 
                        }
569
 
                        if($expression[$i] == '.')
570
 
                        {
571
 
                                if($state == "KEY")
572
 
                                {
573
 
                                        $state="FUNCTION";
574
 
                                        continue;
575
 
                                }
576
 
                                // Support for '.' in KEY
577
 
                                if($state == "FUNCTION")
578
 
                                {
579
 
                                        $state="FUNCTION";
580
 
                                        $key=$key.".".$function;
581
 
                                        $function="";
582
 
                                        continue;
583
 
                                }
584
 
                        }
585
 
                        if($state == "HOST")
586
 
                        {
587
 
                                $host=$host.$expression[$i];
588
 
                                continue;
589
 
                        }
590
 
                        if($state == "KEY")
591
 
                        {
592
 
                                $key=$key.$expression[$i];
593
 
                                continue;
594
 
                        }
595
 
                        if($state == "FUNCTION")
596
 
                        {
597
 
                                $function=$function.$expression[$i];
598
 
                                continue;
599
 
                        }
600
 
                        if($state == "PARAMETER")
601
 
                        {
602
 
                                $parameter=$parameter.$expression[$i];
603
 
                                continue;
604
 
                        }
605
 
                        $exp=$exp.$expression[$i];
 
929
                        if ( $arr[ZBX_EXPRESSION_MACRO_ID] && !isset($ZBX_TR_EXPR_ALLOWED_MACROS[$arr[ZBX_EXPRESSION_MACRO_ID]]) )
 
930
                        {
 
931
                                error('[ie] Unknown macro ['.$arr[ZBX_EXPRESSION_MACRO_ID].']');
 
932
                                return false;
 
933
                        }
 
934
                        else if( !$arr[ZBX_EXPRESSION_MACRO_ID] ) 
 
935
                        {
 
936
                                $s_expr         = &$arr[ZBX_EXPRESSION_SIMPLE_EXPRESSION_ID];
 
937
                                $host           = &$arr[ZBX_EXPRESSION_SIMPLE_EXPRESSION_ID + ZBX_SIMPLE_EXPRESSION_HOST_ID];
 
938
                                $key            = &$arr[ZBX_EXPRESSION_SIMPLE_EXPRESSION_ID + ZBX_SIMPLE_EXPRESSION_KEY_ID];
 
939
                                $function       = &$arr[ZBX_EXPRESSION_SIMPLE_EXPRESSION_ID + ZBX_SIMPLE_EXPRESSION_FUNCTION_NAME_ID];
 
940
                                $parameter      = &$arr[ZBX_EXPRESSION_SIMPLE_EXPRESSION_ID + ZBX_SIMPLE_EXPRESSION_FUNCTION_PARAM_ID];
 
941
 
 
942
                                $item = DBfetch(DBselect('select i.itemid from items i,hosts h'.
 
943
                                        ' where i.key_='.zbx_dbstr($key).
 
944
                                        ' and h.host='.zbx_dbstr($host).
 
945
                                        ' and h.hostid=i.hostid'));
 
946
 
 
947
                                $item = $item["itemid"];
 
948
 
 
949
                                $functionid = get_dbid("functions","functionid");
 
950
 
 
951
                                if ( !DBexecute('insert into functions (functionid,itemid,triggerid,function,parameter)'.
 
952
                                        ' values ('.$functionid.','.$item.','.$triggerid.','.zbx_dbstr($function).','.
 
953
                                        zbx_dbstr($parameter).')'))
 
954
                                {
 
955
                                        return  null;
 
956
                                }
 
957
                                $short_exp = str_replace($s_expr,'{'.$functionid.'}',$short_exp);
 
958
                                $expr = str_replace($s_expr,$ZBX_TR_EXPR_REPLACE_TO,$expr);
 
959
                                continue;
 
960
                        }
 
961
                        $expr = $arr[ZBX_EXPRESSION_LEFT_ID].$ZBX_TR_EXPR_REPLACE_TO.$arr[ZBX_EXPRESSION_RIGHT_ID];
606
962
                }
607
 
                return $exp;
 
963
 
 
964
                return $short_exp;
608
965
        }
609
966
 
610
967
        function        update_trigger_comments($triggerid,$comments)
611
968
        {
612
 
                if(!check_right("Trigger comment","U",$triggerid))
613
 
                {
614
 
                        error("Insufficient permissions");
615
 
                        return  0;
616
 
                }
617
 
 
618
969
                return  DBexecute("update triggers set comments=".zbx_dbstr($comments).
619
970
                        " where triggerid=$triggerid");
620
971
        }
630
981
                        update_trigger_status($db_chd_trigger["triggerid"],$status);
631
982
                }
632
983
 
633
 
                if(!check_right_on_trigger("U",$triggerid))
634
 
                {
635
 
                        error("Insufficient permissions");
636
 
                        return 0;
637
 
                }
638
 
                add_alarm($triggerid,TRIGGER_VALUE_UNKNOWN);
 
984
                add_event($triggerid,TRIGGER_VALUE_UNKNOWN);
639
985
                return  DBexecute("update triggers set status=$status where triggerid=$triggerid");
640
986
        }
641
987
 
642
988
        # "Processor load on {HOSTNAME} is 5" to "Processor load on www.sf.net is 5"
 
989
        function        expand_trigger_description_by_data($row)
 
990
        {
 
991
                if($row)
 
992
                {
 
993
                        if(is_null($row["host"])) $row["host"] = "{HOSTNAME}";
 
994
                        $description = str_replace("{HOSTNAME}", $row["host"],$row["description"]);
 
995
                }
 
996
                else
 
997
                {
 
998
                        $description = "*ERROR*";
 
999
                }
 
1000
                return $description;
 
1001
        }
 
1002
        
643
1003
        function        expand_trigger_description_simple($triggerid)
644
1004
        {
645
 
                $result=DBselect("select distinct t.description,h.host".
646
 
                        " from triggers t,functions f,items i,hosts h".
647
 
                        " where t.triggerid=$triggerid and f.triggerid=t.triggerid".
648
 
                        " and f.itemid=i.itemid and i.hostid=h.hostid");
649
 
 
650
 
 
651
 
                $row = DBfetch($result);
652
 
                if($row)
653
 
                {
654
 
                        $description = str_replace("{HOSTNAME}", $row["host"],$row["description"]);
655
 
                }
656
 
                else
657
 
                {
658
 
                        $result = DBselect("select description from triggers where triggerid=$triggerid");
659
 
                        $row = DBfetch($result);
660
 
                        $description = $row["description"];
661
 
                }
662
 
 
663
 
                return $description;
 
1005
                return expand_trigger_description_by_data(
 
1006
                        DBfetch(
 
1007
                                DBselect("select distinct t.description,h.host".
 
1008
                                        " from triggers t left join functions f on t.triggerid=f.triggerid ".
 
1009
                                        " left join items i on f.itemid=i.itemid ".
 
1010
                                        " left join hosts h on i.hostid=h.hostid ".
 
1011
                                        " where t.triggerid=$triggerid")
 
1012
                                )
 
1013
                        );
664
1014
        }
665
1015
 
666
 
        # "Processor load on %s is 5" to "Processor load on www.sf.net is 5"
667
1016
        function        expand_trigger_description($triggerid)
668
1017
        {
669
1018
                $description=expand_trigger_description_simple($triggerid);
681
1030
                $now = time();
682
1031
                while($row=DBfetch($result))
683
1032
                {
684
 
                        if(!add_alarm($row["triggerid"],TRIGGER_VALUE_UNKNOWN,$now)) continue;
 
1033
                        if(!add_event($row["triggerid"],TRIGGER_VALUE_UNKNOWN,$now)) continue;
685
1034
 
686
1035
                        DBexecute('update triggers set value='.TRIGGER_VALUE_UNKNOWN.' where triggerid='.$row["triggerid"]);
687
1036
                }
688
1037
        }
689
1038
 
690
 
        function add_alarm($triggerid, $value, $time=NULL)
 
1039
        /******************************************************************************
 
1040
         *                                                                            *
 
1041
         * Comments: !!! Don't forget sync code with C !!!                            *
 
1042
         *                                                                            *
 
1043
         ******************************************************************************/
 
1044
        function add_event($triggerid, $value, $time=NULL)
691
1045
        {
692
1046
                if(is_null($time)) $time = time();
693
1047
 
694
 
                $result = DBselect('select value from alarms where triggerid='.$triggerid.' order by clock desc',1);
 
1048
                $result = DBselect('select value,clock from events where objectid='.$triggerid.' and object='.EVENT_OBJECT_TRIGGER.
 
1049
                        ' order by clock desc',1);
695
1050
                $last_value = DBfetch($result);
696
1051
                if($last_value)
697
1052
                {
698
1053
                        if($value == $last_value['value'])
699
1054
                                return false;
700
1055
                }
701
 
                $result = DBexecute('insert into alarms(triggerid,clock,value) values('.$triggerid.','.$time.','.$value.')');
 
1056
                $eventid = get_dbid("events","eventid");
 
1057
                $result = DBexecute('insert into events(eventid,source,object,objectid,clock,value) '.
 
1058
                                ' values('.$eventid.','.EVENT_SOURCE_TRIGGERS.','.EVENT_OBJECT_TRIGGER.','.$triggerid.','.$time.','.$value.')');
702
1059
                if($value == TRIGGER_VALUE_FALSE || $value == TRIGGER_VALUE_TRUE)
703
1060
                {
704
 
                        $alarm_id = DBinsert_id($result,'alarms','alarmid');
705
1061
                        DBexesute('update alerts set retries=3,error=\'Trigger changed its status. WIll not send repeats.\''.
706
1062
                                ' where triggerid='.$triggerid.' and repeats>0 and status='.ALERT_STATUS_NOT_SENT);
707
1063
                }
715
1071
                {
716
1072
                        return $result;
717
1073
                }
718
 
                add_additional_dependencies($triggerid,$depid);
 
1074
                //add_additional_dependencies($triggerid,$depid);
719
1075
                return $result;
720
1076
        }
721
1077
 
722
 
        # Delete Trigger definition
723
 
 
 
1078
        /******************************************************************************
 
1079
         *                                                                            *
 
1080
         * Purpose: Delete Trigger definition                                         *
 
1081
         *                                                                            *
 
1082
         * Comments: !!! Don't forget sync code with C !!!                            *
 
1083
         *                                                                            *
 
1084
         ******************************************************************************/
724
1085
        function        delete_trigger($triggerid)
725
1086
        {
726
1087
                // first delete child triggers
742
1103
                $result=delete_function_by_triggerid($triggerid);
743
1104
                if(!$result)    return  $result;
744
1105
 
745
 
                $result=delete_alarms_by_triggerid($triggerid);
 
1106
                $result=delete_events_by_triggerid($triggerid);
746
1107
                if(!$result)    return  $result;
747
1108
 
748
1109
                $result=delete_services_by_triggerid($triggerid);
755
1116
 
756
1117
                DBexecute("update sysmaps_links set triggerid=NULL where triggerid=$triggerid");
757
1118
                
758
 
                $db_actions = DBselect("select distinct c.actionid from conditions c, triggers t".
759
 
                        " where c.conditiontype=".CONDITION_TYPE_TRIGGER.
760
 
                        " and c.value=t.triggerid and t.triggerid=".$triggerid);
 
1119
        // disable actions
 
1120
                $db_actions = DBselect("select distinct actionid from conditions ".
 
1121
                        " where conditiontype=".CONDITION_TYPE_TRIGGER." and value=".$triggerid);
761
1122
                while($db_action = DBfetch($db_actions))
762
1123
                {
763
1124
                        DBexecute("update actions set status=".ACTION_STATUS_DISABLED.
764
1125
                                " where actionid=".$db_action["actionid"]);
765
1126
                }
 
1127
        // delete action conditions
 
1128
                DBexecute('delete from conditions where conditiontype='.CONDITION_TYPE_TRIGGER.' and value='.$triggerid);
766
1129
 
767
1130
                $trigger = get_trigger_by_triggerid($triggerid);
768
1131
 
770
1133
 
771
1134
                if($result)
772
1135
                {
773
 
                // delete trigger permisions
774
 
                        DBexecute('delete from rights where name=\'Trigger comment\' and id='.$triggerid);
775
 
 
776
1136
                        $msg = "Trigger '".$trigger["description"]."' deleted";
777
1137
                        $trig_host = DBfetch($trig_hosts);
778
1138
                        if($trig_host)
786
1146
 
787
1147
        # Update Trigger definition
788
1148
 
 
1149
        /******************************************************************************
 
1150
         *                                                                            *
 
1151
         * Comments: !!! Don't forget sync code with C !!!                            *
 
1152
         *                                                                            *
 
1153
         ******************************************************************************/
789
1154
        function        update_trigger($triggerid,$expression=NULL,$description=NULL,$priority=NULL,$status=NULL,
790
1155
                $comments=NULL,$url=NULL,$deps=array(),$templateid=0)
791
1156
        {
792
 
                if(!check_right_on_trigger("U",$triggerid))
793
 
                {
794
 
                        error("Insufficient permissions");
795
 
                        return 0;
796
 
                }
797
 
 
798
1157
                $trigger        = get_trigger_by_triggerid($triggerid);
799
1158
                $trig_hosts     = get_hosts_by_triggerid($triggerid);
800
1159
                $trig_host      = DBfetch($trig_hosts);
801
1160
 
802
1161
                if(is_null($expression))
803
1162
                {
 
1163
                        /* Restore expression */
804
1164
                        $expression = explode_exp($trigger["expression"],0);
805
1165
                }
806
 
                else
807
 
                {
808
 
                        if(validate_expression($expression))
809
 
                                return FALSE;
810
 
                }
 
1166
 
 
1167
                if ( !validate_expression($expression) )
 
1168
                        return false;
811
1169
 
812
1170
                $exp_hosts      = get_hosts_by_expression($expression);
813
 
                $chd_hosts      = get_hosts_by_templateid($trig_host["hostid"]);
 
1171
                if( $exp_hosts )
 
1172
                {
 
1173
                        $chd_hosts      = get_hosts_by_templateid($trig_host["hostid"]);
814
1174
 
815
 
                if(DBfetch($chd_hosts))
816
 
                {
817
 
                        $exp_host = DBfetch($exp_hosts);
818
 
                        $db_chd_triggers = get_triggers_by_templateid($triggerid);
819
 
                        while($db_chd_trigger = DBfetch($db_chd_triggers))
 
1175
                        if(DBfetch($chd_hosts))
820
1176
                        {
821
 
                                $chd_trig_hosts = get_hosts_by_triggerid($db_chd_trigger["triggerid"]);
822
 
                                $chd_trig_host = DBfetch($chd_trig_hosts);
 
1177
                                $exp_host = DBfetch($exp_hosts);
 
1178
                                $db_chd_triggers = get_triggers_by_templateid($triggerid);
 
1179
                                while($db_chd_trigger = DBfetch($db_chd_triggers))
 
1180
                                {
 
1181
                                        $chd_trig_hosts = get_hosts_by_triggerid($db_chd_trigger["triggerid"]);
 
1182
                                        $chd_trig_host = DBfetch($chd_trig_hosts);
823
1183
 
824
 
                                $newexpression = str_replace(
825
 
                                        "{".$exp_host["host"].":",
826
 
                                        "{".$chd_trig_host["host"].":",
827
 
                                        $expression);
828
 
                        // recursion
829
 
                                update_trigger(
830
 
                                        $db_chd_trigger["triggerid"],
831
 
                                        $newexpression,
832
 
                                        $description,
833
 
                                        $priority,
834
 
                                        NULL,           // status
835
 
                                        $comments,
836
 
                                        $url,
837
 
                                        $deps,
838
 
                                        $triggerid);
 
1184
                                        $newexpression = str_replace(
 
1185
                                                "{".$exp_host["host"].":",
 
1186
                                                "{".$chd_trig_host["host"].":",
 
1187
                                                $expression);
 
1188
                                // recursion
 
1189
                                        update_trigger(
 
1190
                                                $db_chd_trigger["triggerid"],
 
1191
                                                $newexpression,
 
1192
                                                $description,
 
1193
                                                $priority,
 
1194
                                                NULL,           // status
 
1195
                                                $comments,
 
1196
                                                $url,
 
1197
                                                replace_template_dependences($deps, $chd_trig_host['hostid']),
 
1198
                                                $triggerid);
 
1199
                                }
839
1200
                        }
840
1201
                }
841
1202
 
845
1206
                        return  $result;
846
1207
                }
847
1208
 
848
 
                $expression = implode_exp($expression,$triggerid);
849
 
                add_alarm($triggerid,TRIGGER_VALUE_UNKNOWN);
 
1209
                $expression = implode_exp($expression,$triggerid); /* errors can be ignored cose function must return NULL */
 
1210
 
 
1211
                add_event($triggerid,TRIGGER_VALUE_UNKNOWN);
850
1212
                reset_items_nextcheck($triggerid);
851
1213
 
852
1214
                $sql="update triggers set";
874
1236
                        $trig_host = DBfetch($trig_hosts);
875
1237
                        if($trig_host)
876
1238
                        {
877
 
                                $msg .= " from host '".$trig_host["host"]."'";
 
1239
                                $msg .= " for host '".$trig_host["host"]."'";
878
1240
                        }
879
1241
                        info($msg);
880
1242
                }
881
1243
                return $result;
882
1244
        }
883
1245
 
884
 
        function        check_right_on_trigger($permission,$triggerid)
885
 
        {
886
 
                $result=DBselect("select distinct h.hostid from functions f,items i,hosts h".
887
 
                        " where h.hostid=i.hostid and i.itemid=f.itemid and f.triggerid=$triggerid");
888
 
                while($row=DBfetch($result))
889
 
                        if(check_right("Host",$permission,$row["hostid"]))
890
 
                                return 1;
891
 
 
892
 
                return  0;
893
 
        }
894
 
 
 
1246
        function        check_right_on_trigger_by_triggerid($permission,$triggerid,$accessible_hosts=null)
 
1247
        {
 
1248
                $trigger_data = DBfetch(DBselect('select expression from triggers where triggerid='.$triggerid));
 
1249
 
 
1250
                if(!$trigger_data) return false;
 
1251
 
 
1252
                return check_right_on_trigger_by_expression($permission, explode_exp($trigger_data['expression'], 0), $accessible_hosts);
 
1253
        }
 
1254
 
 
1255
        function        check_right_on_trigger_by_expression($permission,$expression,$accessible_hosts=null)
 
1256
        {
 
1257
                if(is_null($accessible_hosts))
 
1258
                {
 
1259
                        global $USER_DETAILS;
 
1260
                        $accessible_hosts = get_accessible_hosts_by_user($USER_DETAILS, $permission, null, PERM_RES_IDS_ARRAY);
 
1261
                }
 
1262
                if(!is_array($accessible_hosts)) $accessible_hosts = explode(',', $accessible_hosts);
 
1263
 
 
1264
                $db_hosts = get_hosts_by_expression($expression);
 
1265
                while($host_data = DBfetch($db_hosts))
 
1266
                {
 
1267
                        if(!in_array($host_data['hostid'], $accessible_hosts)) return false;
 
1268
                }
 
1269
 
 
1270
                return true;
 
1271
        }
 
1272
 
 
1273
        /******************************************************************************
 
1274
         *                                                                            *
 
1275
         * Comments: !!! Don't forget sync code with C !!!                            *
 
1276
         *                                                                            *
 
1277
         ******************************************************************************/
895
1278
        function        delete_dependencies_by_triggerid($triggerid)
896
1279
        {
897
 
                $db_deps = DBselect("select triggerid_up, triggerid_down from trigger_depends".
898
 
                        " where triggerid_down=".$triggerid);
 
1280
                $db_deps = DBselect('select triggerid_up, triggerid_down from trigger_depends'.
 
1281
                        ' where triggerid_down='.$triggerid);
899
1282
                while($db_dep = DBfetch($db_deps))
900
1283
                {
901
 
                        delete_trigger_dependency($db_dep["triggerid_down"],$db_dep["triggerid_up"]);
902
 
                }
903
 
                return TRUE;
904
 
        }
905
 
 
906
 
        function        delete_trigger_dependency($triggerid_down, $triggerid_up)
907
 
        {
908
 
                $result = DBexecute("select triggerid_up from trigger_depends".
909
 
                        " where triggerid_up=$triggerid_up and triggerid_down=$triggerid_down");
910
 
                while($row=DBfetch($result))
911
 
                {
912
 
                        DBexecute("update triggers set dep_level=dep_level-1".
913
 
                                " where triggerid=".$row["triggerid_up"]);
914
 
                }
915
 
 
916
 
                DBexecute("delete from trigger_depends".
917
 
                        " where triggerid_up=$triggerid_up and triggerid_down=$triggerid_down");
918
 
 
919
 
                return  TRUE;
920
 
        }
921
 
 
 
1284
                        DBexecute('update triggers set dep_level=dep_level-1 where triggerid='.$db_dep['triggerid_up']);
 
1285
                        DBexecute('delete from trigger_depends'.
 
1286
                                ' where triggerid_up='.$db_dep['triggerid_up'].
 
1287
                                ' and triggerid_down='.$db_dep['triggerid_down']);
 
1288
                }
 
1289
                return true;
 
1290
        }
 
1291
 
 
1292
        /******************************************************************************
 
1293
         *                                                                            *
 
1294
         * Comments: !!! Don't forget sync code with C !!!                            *
 
1295
         *                                                                            *
 
1296
         ******************************************************************************/
922
1297
        function        insert_dependency($triggerid_down,$triggerid_up)
923
1298
        {
924
 
                $result=DBexecute("insert into trigger_depends (triggerid_down,triggerid_up)".
925
 
                        " values ($triggerid_down,$triggerid_up)");
 
1299
                $triggerdepid = get_dbid("trigger_depends","triggerdepid");
 
1300
                $result=DBexecute("insert into trigger_depends (triggerdepid,triggerid_down,triggerid_up)".
 
1301
                        " values ($triggerdepid,$triggerid_down,$triggerid_up)");
926
1302
                if(!$result)
927
1303
                {
928
1304
                        return  $result;
930
1306
                return DBexecute("update triggers set dep_level=dep_level+1 where triggerid=$triggerid_up");
931
1307
        }
932
1308
 
933
 
        // If 1 depends on 2, and 2 depends on 3, then add dependency 1->3
 
1309
        /* INCORRECT LOGIC: If 1 depends on 2, and 2 depends on 3, then add dependency 1->3
 
1310
        
934
1311
        function        add_additional_dependencies($triggerid_down,$triggerid_up)
935
1312
        {
936
1313
                $result=DBselect("select triggerid_down from trigger_depends".
947
1324
                        add_additional_dependencies($triggerid_down,$row["triggerid_up"]);
948
1325
                }
949
1326
        }
 
1327
        */
950
1328
 
951
1329
        function        delete_function_by_triggerid($triggerid)
952
1330
        {
953
1331
                return  DBexecute("delete from functions where triggerid=$triggerid");
954
1332
        }
955
1333
 
956
 
        function        delete_alarms_by_triggerid($triggerid)
 
1334
        function        delete_events_by_triggerid($triggerid)
957
1335
        {
958
 
                return  DBexecute("delete from alarms where triggerid=$triggerid");
 
1336
                return  DBexecute('delete from events where objectid='.$triggerid.' and object='.EVENT_OBJECT_TRIGGER);
959
1337
        }
960
1338
 
 
1339
        /******************************************************************************
 
1340
         *                                                                            *
 
1341
         * Comments: !!! Don't forget sync code with C !!!                            *
 
1342
         *                                                                            *
 
1343
         ******************************************************************************/
961
1344
        function        delete_triggers_by_itemid($itemid)
962
1345
        {
963
1346
                $result=DBselect("select triggerid from functions where itemid=$itemid");
971
1354
                return TRUE;
972
1355
        }
973
1356
 
974
 
        # Delete Service definitions by triggerid
975
 
 
 
1357
        /******************************************************************************
 
1358
         *                                                                            *
 
1359
         * Purpose: Delete Service definitions by triggerid                           *
 
1360
         *                                                                            *
 
1361
         * Comments: !!! Don't forget sync code with C !!!                            *
 
1362
         *                                                                            *
 
1363
         ******************************************************************************/
976
1364
        function        delete_services_by_triggerid($triggerid)
977
1365
        {
978
1366
                $result = DBselect("select serviceid from services where triggerid=$triggerid");
983
1371
                return  TRUE;
984
1372
        }
985
1373
 
 
1374
        /*
 
1375
         * Function: cmp_triggers
 
1376
         *
 
1377
         * Description: 
 
1378
         *     compate triggers by expression
 
1379
         *     
 
1380
         * Author: 
 
1381
         *     Eugene Grigorjev (eugene.grigorjev@zabbix.com)
 
1382
         *
 
1383
         * Comments: !!! Don't forget sync code with C !!!
 
1384
         *
 
1385
         */
986
1386
        function        cmp_triggers($triggerid1, $triggerid2)  // compare EXPRESSION !!!
987
1387
        {
988
1388
                $trig1 = get_trigger_by_triggerid($triggerid1);
1013
1413
                return strcmp($expr1,$trig2["expression"]);
1014
1414
        }
1015
1415
 
1016
 
        function        delete_template_triggers_by_hostid($hostid)
 
1416
        /*
 
1417
         * Function: delete_template_triggers
 
1418
         *
 
1419
         * Description: 
 
1420
         *     Delete template triggers
 
1421
         *     
 
1422
         * Author: 
 
1423
         *     Eugene Grigorjev (eugene.grigorjev@zabbix.com)
 
1424
         *
 
1425
         * Comments: !!! Don't forget sync code with C !!!
 
1426
         *
 
1427
         */
 
1428
        function        delete_template_triggers($hostid, $templateid = null, $unlink_mode = false)
1017
1429
        {
1018
1430
                $triggers = get_triggers_by_hostid($hostid);
1019
1431
                while($trigger = DBfetch($triggers))
1020
1432
                {
1021
1433
                        if($trigger["templateid"]==0)   continue;
1022
 
                        delete_trigger($trigger["triggerid"]);
 
1434
 
 
1435
                        if($templateid != null)
 
1436
                        {
 
1437
                                if( !is_array($templateid))
 
1438
                                        $templateid = array($templateid);
 
1439
 
 
1440
                                $db_tmp_hosts = get_hosts_by_triggerid($trigger["templateid"]);
 
1441
                                $tmp_host = DBfetch($db_tmp_hosts);
 
1442
 
 
1443
                                if( !in_array($tmp_host["hostid"], $templateid) )
 
1444
                                        continue;
 
1445
                        }
 
1446
 
 
1447
                        if($unlink_mode)
 
1448
                        {
 
1449
                                if(DBexecute("update triggers set templateid=0 where triggerid=".$trigger["triggerid"]))
 
1450
                                {
 
1451
                                        info("Trigger '".$trigger["description"]."' unlinked");
 
1452
                                }
 
1453
                        }
 
1454
                        else
 
1455
                        {
 
1456
                                delete_trigger($trigger["triggerid"]);
 
1457
                        }
1023
1458
                }
1024
1459
 
1025
1460
                return TRUE;
1026
1461
        }
1027
1462
        
1028
 
        function        sync_triggers_with_template($hostid)
 
1463
        /*
 
1464
         * Function: copy_template_triggers
 
1465
         *
 
1466
         * Description: 
 
1467
         *     Copy triggers from template
 
1468
         *     
 
1469
         * Author: 
 
1470
         *     Eugene Grigorjev (eugene.grigorjev@zabbix.com)
 
1471
         *
 
1472
         * Comments: !!! Don't forget sync code with C !!!
 
1473
         *
 
1474
         */
 
1475
        function        copy_template_triggers($hostid, $templateid = null, $copy_mode = false)
1029
1476
        {
1030
 
                $host = get_host_by_hostid($hostid);    
1031
 
                $triggers = get_triggers_by_hostid($host["templateid"]);
 
1477
                if(null == $templateid)
 
1478
                {
 
1479
                        $templateid = array_keys(get_templates_by_hostid($hostid));
 
1480
                }
 
1481
 
 
1482
                if(is_array($templateid))
 
1483
                {
 
1484
                        foreach($templateid as $id)
 
1485
                                copy_template_triggers($hostid, $id, $copy_mode); // attention recursion
 
1486
                        return;
 
1487
                }
 
1488
 
 
1489
                $triggers = get_triggers_by_hostid($templateid);
1032
1490
                while($trigger = DBfetch($triggers))
1033
1491
                {
1034
 
                        copy_trigger_to_host($trigger["triggerid"], $hostid);
1035
 
                }
1036
 
        }
1037
 
 
1038
 
        function        get_triggers_overview($groupid)
1039
 
        {
 
1492
                        copy_trigger_to_host($trigger["triggerid"], $hostid, $copy_mode);
 
1493
                }
 
1494
 
 
1495
                update_template_dependences_for_host($hostid);
 
1496
        }
 
1497
 
 
1498
        /*
 
1499
         * Function: update_template_dependences_for_host
 
1500
         *
 
1501
         * Description: 
 
1502
         *     Update template triggers
 
1503
         *     
 
1504
         * Author: 
 
1505
         *     Eugene Grigorjev (eugene.grigorjev@zabbix.com)
 
1506
         *
 
1507
         * Comments: !!! Don't forget sync code with C !!!
 
1508
         *
 
1509
         */
 
1510
        function        update_template_dependences_for_host($hostid)
 
1511
        {
 
1512
                $db_triggers = get_triggers_by_hostid($hostid);
 
1513
                while($trigger_data = DBfetch($db_triggers))
 
1514
                {
 
1515
                        $db_chd_triggers = get_triggers_by_templateid($trigger_data['triggerid']);
 
1516
                        while($chd_trigger_data = DBfetch($db_chd_triggers))
 
1517
                                update_trigger($chd_trigger_data['triggerid'],
 
1518
                                        /*$expression*/         NULL,
 
1519
                                        /*$description*/        NULL,
 
1520
                                        /*$priority*/           NULL,
 
1521
                                        /*$status*/             NULL,
 
1522
                                        /*$comments*/           NULL,
 
1523
                                        /*$url*/                NULL,
 
1524
                                        replace_template_dependences(
 
1525
                                                get_trigger_dependences_by_triggerid($trigger_data['triggerid']),
 
1526
                                                $hostid),
 
1527
                                        $trigger_data['triggerid']);
 
1528
 
 
1529
                }
 
1530
        }
 
1531
 
 
1532
        /*
 
1533
         * Function: get_triggers_overview
 
1534
         *
 
1535
         * Description: 
 
1536
         *     Retrive table with overview of triggers
 
1537
         *     
 
1538
         * Author: 
 
1539
         *     Eugene Grigorjev (eugene.grigorjev@zabbix.com)
 
1540
         *
 
1541
         * Comments: !!! Don't forget sync code with C !!!
 
1542
         *
 
1543
         */
 
1544
        function        get_triggers_overview($groupid, $nodeid)
 
1545
        {
 
1546
                global $USER_DETAILS;
 
1547
 
1040
1548
                $table = new CTableInfo(S_NO_TRIGGERS_DEFINED);
1041
1549
                if($groupid > 0)
1042
1550
                {
1045
1553
                        $group_where = ' where';
1046
1554
                }
1047
1555
 
1048
 
                $result=DBselect('select distinct t.description,t.value,t.lastchange,h.hostid,h.host'.
 
1556
                $result=DBselect('select distinct t.triggerid,t.description,t.value,t.priority,t.lastchange,h.hostid,h.host'.
1049
1557
                        ' from hosts h,items i,triggers t, functions f '.$group_where.
1050
1558
                        ' h.status='.HOST_STATUS_MONITORED.' and h.hostid=i.hostid and i.itemid=f.itemid and f.triggerid=t.triggerid'.
1051
 
                        ' and t.status='.TRIGGER_STATUS_ENABLED.
 
1559
                        ' and h.hostid in ('.get_accessible_hosts_by_user($USER_DETAILS,PERM_READ_ONLY, null, null, $nodeid).') '.
 
1560
                        ' and t.status='.TRIGGER_STATUS_ENABLED.' and i.status='.ITEM_STATUS_ACTIVE.
1052
1561
                        ' order by t.description');
1053
1562
                unset($triggers);
1054
1563
                unset($hosts);
1055
1564
                while($row = DBfetch($result))
1056
1565
                {
1057
 
                        if(!check_right('Host','R',$row['hostid'])) continue;
1058
1566
                        $hosts[$row['host']] = $row['host'];
1059
 
                        $triggers[$row['description']][$row['host']] = array('value' => $row['value'], 'lastchange' => $row['lastchange']);
 
1567
                        $triggers[$row['description']][$row['host']] = array(
 
1568
                                'hostid'        => $row['hostid'], 
 
1569
                                'triggerid'     => $row['triggerid'], 
 
1570
                                'value'         => $row['value'], 
 
1571
                                'lastchange'    => $row['lastchange'],
 
1572
                                'priority'      => $row['priority']);
1060
1573
                }
1061
1574
                if(!isset($hosts))
1062
1575
                {
1076
1589
                        $table_row = array(nbsp($descr));
1077
1590
                        foreach($hosts as $hostname)
1078
1591
                        {
1079
 
                                $style = NULL;
 
1592
                                $css_class = NULL;
 
1593
 
 
1594
                                unset($tr_ov_menu);
 
1595
                                $ack = null;
1080
1596
                                if(isset($trhosts[$hostname]))
1081
1597
                                {
1082
 
                                        if($trhosts[$hostname]['value'] == TRIGGER_VALUE_FALSE)         $style = 'normal';
1083
 
                                        elseif($trhosts[$hostname]['value'] == TRIGGER_VALUE_UNKNOWN)   $style = 'unknown_trigger';
1084
 
                                        else                                                            $style = 'high';
1085
 
 
1086
 
                                        if((time(NULL)-$trhosts[$hostname]['lastchange'])<300)          $style .= '_blink1';
1087
 
                                        elseif((time(NULL)-$trhosts[$hostname]['lastchange'])<900)      $style .= '_blink2';
1088
 
                                }
1089
 
                                array_push($table_row,new CCol(SPACE,$style));
 
1598
                                        unset($ack_menu);
 
1599
                                        switch($trhosts[$hostname]['value'])
 
1600
                                        {
 
1601
                                                case TRIGGER_VALUE_TRUE:
 
1602
                                                        $css_class = get_severity_style($trhosts[$hostname]['priority']);
 
1603
                                                        if( ($ack = get_last_event_by_triggerid($trhosts[$hostname]['triggerid'])) )
 
1604
                                                                $ack_menu = array(S_ACKNOWLEDGE, 'acknow.php?eventid='.$ack['eventid'], array('tw'=>'_blank'));
 
1605
 
 
1606
                                                        if ( 1 == $ack['acknowledged'] )
 
1607
                                                                $ack = new CImg('images/general/tick.png','ack');
 
1608
                                                        else
 
1609
                                                                $ack = null;
 
1610
 
 
1611
                                                        break;
 
1612
                                                case TRIGGER_VALUE_FALSE:
 
1613
                                                        $css_class = 'normal';
 
1614
                                                        break;
 
1615
                                                default:
 
1616
                                                        $css_class = 'unknown_trigger';
 
1617
                                        }
 
1618
 
 
1619
                                        $style = 'cursor: pointer; ';
 
1620
 
 
1621
                                        if((time(NULL)-$trhosts[$hostname]['lastchange'])<300)
 
1622
                                                $style .= 'background-image: url(images/gradients/blink1.gif); '.
 
1623
                                                        'background-position: top left; '.
 
1624
                                                        'background-repeat: repeate;';
 
1625
                                        elseif((time(NULL)-$trhosts[$hostname]['lastchange'])<900)
 
1626
                                                $style .= 'background-image: url(images/gradients/blink2.gif); '.
 
1627
                                                        'background-position: top left; '.
 
1628
                                                        'background-repeat: repeate;';
 
1629
 
 
1630
                                        unset($item_menu);
 
1631
                                        $tr_ov_menu = array(
 
1632
                                                /* name, url, (target [tw], statusbar [sb]), css, submenu */
 
1633
                                                array(S_TRIGGER, null,  null, 
 
1634
                                                        array('outer'=> array('pum_oheader'), 'inner'=>array('pum_iheader'))
 
1635
                                                        ),
 
1636
                                                array(S_EVENTS, 'tr_events.php?triggerid='.$trhosts[$hostname]['triggerid'], array('tw'=>'_blank'))
 
1637
                                                );
 
1638
 
 
1639
                                        if(isset($ack_menu)) $tr_ov_menu[] = $ack_menu;
 
1640
 
 
1641
                                        $db_items = DBselect('select distinct i.itemid, i.description, i.key_, i.value_type '.
 
1642
                                                ' from items i, functions f '.
 
1643
                                                ' where f.itemid=i.itemid and f.triggerid='.$trhosts[$hostname]['triggerid']);
 
1644
 
 
1645
                                        while($item_data = DBfetch($db_items))
 
1646
                                        {
 
1647
                                                $description = item_description($item_data['description'], $item_data['key_']);
 
1648
                                                switch($item_data['value_type'])
 
1649
                                                {
 
1650
                                                        case ITEM_VALUE_TYPE_UINT64:
 
1651
                                                        case ITEM_VALUE_TYPE_FLOAT:
 
1652
                                                                $action = 'showgraph';
 
1653
                                                                $status_bar = S_SHOW_GRAPH_OF_ITEM.' \''.$description.'\'';
 
1654
                                                                break;
 
1655
                                                        case ITEM_VALUE_TYPE_LOG:
 
1656
                                                        case ITEM_VALUE_TYPE_STR:
 
1657
                                                        case ITEM_VALUE_TYPE_TEXT:
 
1658
                                                        default:
 
1659
                                                                $action = 'showlatest';
 
1660
                                                                $status_bar = S_SHOW_VALUES_OF_ITEM.' \''.$description.'\'';
 
1661
                                                                break;
 
1662
                                                }
 
1663
                                                
 
1664
                                                if(strlen($description) > 25) $description = substr($description,0,22).'...';
 
1665
 
 
1666
                                                $item_menu[$action][] = array(
 
1667
                                                        $description,
 
1668
                                                        'history.php?action='.$action.'&itemid='.$item_data['itemid'].'&period=3600',
 
1669
                                                         array('tw'=>'_blank', 'sb'=>$status_bar));
 
1670
                                        }
 
1671
                                        if(isset($item_menu['showgraph']))
 
1672
                                        {
 
1673
                                                $tr_ov_menu[] = array(S_GRAPHS, null, null,
 
1674
                                                        array('outer'=> array('pum_oheader'), 'inner'=>array('pum_iheader'))
 
1675
                                                        );
 
1676
                                                $tr_ov_menu = array_merge($tr_ov_menu, $item_menu['showgraph']);
 
1677
                                        }
 
1678
                                        if(isset($item_menu['showlatest']))
 
1679
                                        {
 
1680
                                                $tr_ov_menu[] = array(S_VALUES, null, null, 
 
1681
                                                        array('outer'=> array('pum_oheader'), 'inner'=>array('pum_iheader'))
 
1682
                                                        );
 
1683
                                                $tr_ov_menu = array_merge($tr_ov_menu, $item_menu['showlatest']);
 
1684
                                        }
 
1685
 
 
1686
                                        unset($item_menu);
 
1687
                                }
 
1688
 
 
1689
                                $status_col = new CCol(array(SPACE, $ack),$css_class);
 
1690
                                if(isset($style))
 
1691
                                {
 
1692
                                        $status_col->AddOption('style', $style);
 
1693
                                }
 
1694
 
 
1695
                                if(isset($tr_ov_menu))
 
1696
                                {
 
1697
                                        $tr_ov_menu  = new CPUMenu($tr_ov_menu,170);
 
1698
                                        $status_col->OnClick($tr_ov_menu->GetOnActionJS());
 
1699
                                        $status_col->AddAction('onmouseover',
 
1700
                                                'this.old_border=this.style.border; this.style.border=\'1px dotted #0C0CF0\'');
 
1701
                                        $status_col->AddAction('onmouseout', 'this.style.border=this.old_border;');
 
1702
                                }
 
1703
                                array_push($table_row,$status_col);
1090
1704
                        }
1091
1705
                        $table->AddRow($table_row);
1092
1706
                }
1093
1707
                return $table;
1094
1708
        }
 
1709
 
 
1710
        function        get_function_by_functionid($functionid)
 
1711
        {
 
1712
                $result=DBselect("select * from functions where functionid=$functionid");
 
1713
                $row=DBfetch($result);
 
1714
                if($row)
 
1715
                {
 
1716
                        return  $row;
 
1717
                }
 
1718
                else
 
1719
                {
 
1720
                        error("No function with functionid=[$functionid]");
 
1721
                }
 
1722
                return  $item;
 
1723
        }
 
1724
 
 
1725
        function        calculate_availability($triggerid,$period_start,$period_end)
 
1726
        {
 
1727
                $sql='select count(*) as cnt,min(clock) as minn,max(clock) as maxx from events '.
 
1728
                        ' where objectid='.$triggerid.' and object='.EVENT_OBJECT_TRIGGER;
 
1729
 
 
1730
                if($period_start!=0)    $sql .= ' and clock>='.$period_start;
 
1731
                if($period_end!=0)      $sql .= ' and clock<='.$period_end;
 
1732
 
 
1733
                $row=DBfetch(DBselect($sql));
 
1734
                if($row["cnt"]>0)
 
1735
                {
 
1736
                        $min=$row["minn"];
 
1737
                        $max=$row["maxx"];
 
1738
                }
 
1739
                else
 
1740
                {
 
1741
                        if(($period_start==0)&&($period_end==0))
 
1742
                        {
 
1743
                                $max=time();
 
1744
                                $min=$max-24*3600;
 
1745
                        }
 
1746
                        else
 
1747
                        {
 
1748
                                $ret["true_time"]       = 0;
 
1749
                                $ret["false_time"]      = 0;
 
1750
                                $ret["unknown_time"]    = 0;
 
1751
                                $ret["true"]            = 0;
 
1752
                                $ret["false"]           = 0;
 
1753
                                $ret["unknown"]         = 100;
 
1754
                                return $ret;
 
1755
                        }
 
1756
                }
 
1757
 
 
1758
                $result=DBselect('select clock,value from events where objectid='.$triggerid.' and object='.EVENT_OBJECT_TRIGGER
 
1759
                        .' and clock>='.$min.' and clock<='.$max);
 
1760
 
 
1761
                $state          = -1;
 
1762
                $true_time      = 0;
 
1763
                $false_time     = 0;
 
1764
                $unknown_time   = 0;
 
1765
                $time           = $min;
 
1766
 
 
1767
                if(($period_start==0)&&($period_end==0))
 
1768
                {
 
1769
                        $max=time();
 
1770
                }
 
1771
                $rows=0;
 
1772
                while($row=DBfetch($result))
 
1773
                {
 
1774
                        $clock=$row["clock"];
 
1775
                        $value=$row["value"];
 
1776
 
 
1777
                        $diff=$clock-$time;
 
1778
 
 
1779
                        $time=$clock;
 
1780
 
 
1781
                        if($state==-1)
 
1782
                        {
 
1783
                                $state=$value;
 
1784
                                if($state == 0)
 
1785
                                {
 
1786
                                        $false_time+=$diff;
 
1787
                                }
 
1788
                                if($state == 1)
 
1789
                                {
 
1790
                                        $true_time+=$diff;
 
1791
                                }
 
1792
                                if($state == 2)
 
1793
                                {
 
1794
                                        $unknown_time+=$diff;
 
1795
                                }
 
1796
                        }
 
1797
                        else if($state==0)
 
1798
                        {
 
1799
                                $false_time+=$diff;
 
1800
                                $state=$value;
 
1801
                        }
 
1802
                        else if($state==1)
 
1803
                        {
 
1804
                                $true_time+=$diff;
 
1805
                                $state=$value;
 
1806
                        }
 
1807
                        else if($state==2)
 
1808
                        {
 
1809
                                $unknown_time+=$diff;
 
1810
                                $state=$value;
 
1811
                        }
 
1812
                        $rows++;
 
1813
                }
 
1814
 
 
1815
                if($rows==0)
 
1816
                {
 
1817
                        $trigger = get_trigger_by_triggerid($triggerid);
 
1818
                        $state = $trigger['value'];
 
1819
                }
 
1820
                
 
1821
                if($state==0)
 
1822
                {
 
1823
                        $false_time=$false_time+$max-$time;
 
1824
                }
 
1825
                elseif($state==1)
 
1826
                {
 
1827
                        $true_time=$true_time+$max-$time;
 
1828
                }
 
1829
                elseif($state==3)
 
1830
                {
 
1831
                        $unknown_time=$unknown_time+$max-$time;
 
1832
                }
 
1833
 
 
1834
                $total_time=$true_time+$false_time+$unknown_time;
 
1835
 
 
1836
                if($total_time==0)
 
1837
                {
 
1838
                        $ret["true_time"]       = 0;
 
1839
                        $ret["false_time"]      = 0;
 
1840
                        $ret["unknown_time"]    = 0;
 
1841
                        $ret["true"]            = 0;
 
1842
                        $ret["false"]           = 0;
 
1843
                        $ret["unknown"]         = 100;
 
1844
                }
 
1845
                else
 
1846
                {
 
1847
                        $ret["true_time"]       = $true_time;
 
1848
                        $ret["false_time"]      = $false_time;
 
1849
                        $ret["unknown_time"]    = $unknown_time;
 
1850
                        $ret["true"]            = (100*$true_time)/$total_time;
 
1851
                        $ret["false"]           = (100*$false_time)/$total_time;
 
1852
                        $ret["unknown"]         = (100*$unknown_time)/$total_time;
 
1853
                }
 
1854
                return $ret;
 
1855
        }
 
1856
 
1095
1857
?>