1/*
2** Zabbix
3** Copyright (C) 2001-2021 Zabbix SIA
4**
5** This program is free software; you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation; either version 2 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program; if not, write to the Free Software
17** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18**/
19
20package file
21
22import (
23	"bufio"
24	"errors"
25	"fmt"
26	"math"
27	"regexp"
28	"strconv"
29	"time"
30)
31
32func (p *Plugin) exportRegmatch(params []string) (result interface{}, err error) {
33	var startline, endline, curline uint64
34
35	start := time.Now()
36
37	if len(params) > 5 {
38		return nil, errors.New("Too many parameters.")
39	}
40	if len(params) < 1 || "" == params[0] {
41		return nil, errors.New("Invalid first parameter.")
42	}
43	if len(params) < 2 || "" == params[1] {
44		return nil, errors.New("Invalid second parameter.")
45	}
46
47	var encoder string
48	if len(params) > 2 {
49		encoder = params[2]
50	}
51
52	if len(params) < 4 || "" == params[3] {
53		startline = 0
54	} else {
55		startline, err = strconv.ParseUint(params[3], 10, 32)
56		if err != nil {
57			return nil, errors.New("Invalid fourth parameter.")
58		}
59	}
60	if len(params) < 5 || "" == params[4] {
61		endline = math.MaxUint64
62	} else {
63		endline, err = strconv.ParseUint(params[4], 10, 32)
64		if err != nil {
65			return nil, errors.New("Invalid fifth parameter.")
66		}
67	}
68	if startline > endline {
69		return nil, errors.New("Start line parameter must not exceed end line.")
70	}
71
72	file, err := stdOs.Open(params[0])
73	if err != nil {
74		return nil, fmt.Errorf("Cannot open file %s: %s", params[0], err)
75	}
76	defer file.Close()
77
78	// Start reading from the file with a reader.
79	scanner := bufio.NewScanner(file)
80	curline = 0
81	ret := 0
82	r, err := regexp.Compile(params[1])
83	if err != nil {
84		return nil, fmt.Errorf("Cannot compile regular expression %s: %s", params[1], err)
85	}
86
87	for scanner.Scan() {
88		elapsed := time.Since(start)
89		if elapsed.Seconds() > float64(p.options.Timeout) {
90			return nil, errors.New("Timeout while processing item.")
91		}
92
93		curline++
94		if curline >= startline {
95			if match := r.Match(decode(encoder, scanner.Bytes())); match {
96				ret = 1
97			}
98		}
99		if curline >= endline {
100			break
101		}
102	}
103	return ret, nil
104}
105