-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcclogconv.go
136 lines (116 loc) · 2.78 KB
/
cclogconv.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package cclogconv
import (
"bufio"
"flag"
"fmt"
"github.com/oschwald/geoip2-golang"
"io"
"net"
"os"
"regexp"
"strings"
)
const (
name = "cclogconv"
version = "1.3.9"
)
// These are the exit code definitions.
const (
ExitCodeOK = iota
ExitCodeError
)
// CCLogConv type
type CCLogConv struct {
Out, Err io.Writer
}
// Run CCLogConv
func (cl CCLogConv) Run(args []string) int {
// Define option flag parse
flags := flag.NewFlagSet(name, flag.ContinueOnError)
flags.SetOutput(cl.Err)
var (
mmdbFilePath string
selectCC string
notAdd bool
reverseCond bool
)
flags.BoolVar(¬Add, "n", false, "Not adding country code")
flags.BoolVar(&reverseCond, "v", false, "Reverse condition for cc option")
flags.StringVar(&selectCC, "cc", "", "Only displays line including this country's ip")
flags.StringVar(&mmdbFilePath, "data", "/usr/share/GeoIP2/GeoLite2-Country.mmdb", "GeoIP2 Database Filename")
if err := flags.Parse(args[0:]); err != nil {
return ExitCodeError
}
if selectCC == "" {
exitCode := ExitCodeOK
if notAdd {
fmt.Fprintln(cl.Err, "n option must be used with cc option.")
exitCode = ExitCodeError
}
if reverseCond {
fmt.Fprintln(cl.Err, "v option must be used with cc option.")
exitCode = ExitCodeError
}
if exitCode != ExitCodeOK {
return exitCode
}
}
filter := filter{
in: os.Stdin,
out: cl.Out,
}
if err := filter.start(mmdbFilePath, selectCC, notAdd, reverseCond); err != nil {
fmt.Fprintf(cl.Err, "%s\n", err)
}
return ExitCodeOK
}
type filter struct {
in io.Reader
out io.Writer
}
func (f filter) start(mmdbFilePath string, selectCc string, nFlag bool, vFlag bool) error {
var lineBuf = ""
db, err := geoip2.Open(mmdbFilePath)
if err != nil {
return err
}
defer db.Close()
// If you are using strings that may be invalid, check that ip is not nil
re, _ := regexp.Compile("^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$")
var sc = bufio.NewScanner(f.in)
for sc.Scan() {
var ccMatchFlag = false
lineBuf = ""
words := strings.Fields(sc.Text())
for _, word := range words {
if re.MatchString(word) {
ip := net.ParseIP(word)
record, err := db.City(ip)
if err != nil {
return err
}
cc := record.Country.IsoCode
if ccMatchFlag || cc == selectCc {
ccMatchFlag = true
}
if cc == "" {
cc = "-"
}
if nFlag == false {
lineBuf += fmt.Sprintf("%s ", cc)
}
lineBuf = lineBuf + fmt.Sprintf("%s ", word)
} else {
lineBuf += fmt.Sprintf("%s ", word)
}
}
if ((selectCc == "" || ccMatchFlag) && !vFlag) || (!(selectCc == "" || ccMatchFlag) && vFlag) {
fmt.Fprintln(f.out, strings.TrimRight(lineBuf, " "))
}
lineBuf = ""
}
if err := sc.Err(); err != nil {
return err
}
return nil
}