Skip to content

Commit

Permalink
Merge branch 'release/0.3.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
axllent committed Feb 5, 2024
2 parents ec6b12d + be0c0aa commit be5c67b
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 52 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## [0.3.0]

- Only download database update if missing locally or update is newer than local database
- Code cleanup
- Update Go modules


## [0.2.3]

- Update go modules
Expand Down
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ TAG=`git describe --tags`
VERSION ?= `git describe --tags`
LDFLAGS=-ldflags "-s -w -X main.version=${VERSION} -X main.licenseKey=${LICENSEKEY}"

build = echo "\n\nBuilding $(1)-$(2)" && CGO_ENABLED=0 GOOS=$(1) GOARCH=$(2) go build ${LDFLAGS} -o dist/goiplookup_${VERSION}_$(1)_$(2) \
build = echo "\n\nBuilding $(1)-$(2)" && GO386=softfloat CGO_ENABLED=0 GOOS=$(1) GOARCH=$(2) go build ${LDFLAGS} -o dist/goiplookup_${VERSION}_$(1)_$(2) \
&& bzip2 dist/goiplookup_${VERSION}_$(1)_$(2)

geoiplookup: goiplookup.go
Expand All @@ -20,4 +20,5 @@ release:
$(call build,linux,arm)
$(call build,linux,arm64)
$(call build,darwin,amd64)
$(call build,darwin,arm64)

8 changes: 3 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@ go 1.13

require (
github.com/axllent/ghru v1.2.1
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/oschwald/geoip2-golang v1.4.0
github.com/oschwald/maxminddb-golang v1.8.0 // indirect
github.com/oschwald/geoip2-golang v1.9.0
github.com/oschwald/maxminddb-golang v1.12.0 // indirect
github.com/spf13/pflag v1.0.5
golang.org/x/sys v0.0.0-20210105210732-16f7687f5001 // indirect
golang.org/x/sys v0.16.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)
35 changes: 17 additions & 18 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,38 @@ github.com/axllent/ghru v1.2.1/go.mod h1:YgznIILRJpnII5x8N080q/G8Milzk3sy9Sh4dV1
github.com/axllent/semver v0.0.1 h1:QqF+KSGxgj8QZzSXAvKFqjGWE5792ksOnQhludToK8E=
github.com/axllent/semver v0.0.1/go.mod h1:2xSPzvG8n9mRfdtxSvWvfTfQGWfHsMsHO1iZnKATMSc=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/oschwald/geoip2-golang v1.4.0 h1:5RlrjCgRyIGDz/mBmPfnAF4h8k0IAcRv9PvrpOfz+Ug=
github.com/oschwald/geoip2-golang v1.4.0/go.mod h1:8QwxJvRImBH+Zl6Aa6MaIcs5YdlZSTKtzmPGzQqi9ng=
github.com/oschwald/maxminddb-golang v1.6.0/go.mod h1:DUJFucBg2cvqx42YmDa/+xHvb0elJtOm3o4aFQ/nb/w=
github.com/oschwald/maxminddb-golang v1.8.0 h1:Uh/DSnGoxsyp/KYbY1AuP0tYEwfs0sCph9p/UMXK/Hk=
github.com/oschwald/maxminddb-golang v1.8.0/go.mod h1:RXZtst0N6+FY/3qCNmZMBApR19cdQj43/NM9VkrNAis=
github.com/oschwald/geoip2-golang v1.9.0 h1:uvD3O6fXAXs+usU+UGExshpdP13GAqp4GBrzN7IgKZc=
github.com/oschwald/geoip2-golang v1.9.0/go.mod h1:BHK6TvDyATVQhKNbQBdrj9eAvuwOMi2zSFXizL3K81Y=
github.com/oschwald/maxminddb-golang v1.11.0/go.mod h1:YmVI+H0zh3ySFR3w+oz8PCfglAFj3PuCmui13+P9zDg=
github.com/oschwald/maxminddb-golang v1.12.0 h1:9FnTOD0YOhP7DGxGsq4glzpGy5+w7pq50AS6wALUMYs=
github.com/oschwald/maxminddb-golang v1.12.0/go.mod h1:q0Nob5lTCqyQ8WT6FYgS1L7PXKVVbgiymefNwIjPzgY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/sys v0.0.0-20191224085550-c709ea063b76/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210105210732-16f7687f5001 h1:/dSxr6gT0FNI1MO5WLJo8mTmItROeOKTkDn+7OwWBos=
golang.org/x/sys v0.0.0-20210105210732-16f7687f5001/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
33 changes: 17 additions & 16 deletions goiplookup.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// Package main is the main application
package main

import (
"fmt"
"os"
"runtime"

"github.com/axllent/ghru"
flag "github.com/spf13/pflag"
Expand All @@ -13,9 +13,9 @@ import (
var (
country bool
iso bool
showhelp bool
verboseoutput bool
showversion bool
showHelp bool
verboseOutput bool
showVersion bool
dataDir string
licenseKey string // GeoLite2 license key for updating
version = "dev"
Expand All @@ -28,23 +28,24 @@ const (

// Main function
func main() {
// alternate default path for OSX
if runtime.GOOS == "darwin" {
flag.StringVarP(&dataDir, "dir", "d", "/usr/local/share/GeoIP", "database directory or file")
} else {
flag.StringVarP(&dataDir, "dir", "d", "/usr/share/GeoIP", "database directory or file")

p := "/usr/share/GeoIP"
if isDir("/usr/local/share/GeoIP") {
// alternate default path for OSX or custom
p = "/usr/local/share/GeoIP"
}
flag.StringVarP(&dataDir, "dir", "d", p, "database directory or file")

flag.BoolVarP(&country, "country", "c", false, "return country name")
flag.BoolVarP(&iso, "iso", "i", false, "return country iso code")
flag.BoolVarP(&showhelp, "help", "h", false, "show help")
flag.BoolVarP(&verboseoutput, "verbose", "v", false, "verbose/debug output")
flag.BoolVarP(&showversion, "version", "V", false, "show version number")
flag.BoolVarP(&showHelp, "help", "h", false, "show help")
flag.BoolVarP(&verboseOutput, "verbose", "v", false, "verbose/debug output")
flag.BoolVarP(&showVersion, "version", "V", false, "show version number")

// parse flags
flag.Parse()

if showversion {
if showVersion {
fmt.Println(fmt.Sprintf("Version %s", version))

latest, _, _, err := ghru.Latest("axllent/goiplookup", "goiplookup")
Expand All @@ -54,8 +55,8 @@ func main() {
os.Exit(0)
}

if len(flag.Args()) != 1 || showhelp {
ShowUsage()
if len(flag.Args()) != 1 || showHelp {
showUsage()
return
}

Expand All @@ -79,7 +80,7 @@ func main() {
}

// ShowUsage prints the help function
var ShowUsage = func() {
var showUsage = func() {
fmt.Printf("Usage: %s [-i] [-c] [-d <database directory>] <ipaddress|hostname|db-update|self-update>\n", os.Args[0])
fmt.Println("\nGoiplookup uses the GeoLite2-Country database to find the Country that an IP address or hostname originates from.")
fmt.Println("\nOptions:")
Expand Down
78 changes: 67 additions & 11 deletions updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ package main
import (
"archive/tar"
"compress/gzip"
"errors"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"path"
"path/filepath"
"regexp"
"time"

"github.com/oschwald/geoip2-golang"
)
Expand All @@ -29,10 +32,21 @@ func UpdateGeoLite2Country() {

dbUpdateURL := fmt.Sprintf("https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country&license_key=%s&suffix=tar.gz", key)

updateRequired, err := requiresDBUpdate(dbUpdateURL)
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
}

if !updateRequired {
Verbose("No database update available")
os.Exit(0)
}

Verbose("Updating GeoLite2-Country.mmdb")

tmpDir := os.TempDir()
gzfile := filepath.Join(tmpDir, "GeoLite2-Country.tar.gz")
gzFile := filepath.Join(tmpDir, "GeoLite2-Country.tar.gz")

// check the output directory is writeable
if _, err := os.Stat(dataDir); os.IsNotExist(err) {
Expand All @@ -44,29 +58,71 @@ func UpdateGeoLite2Country() {
os.Exit(1)
}

if err := DownloadToFile(gzfile, dbUpdateURL); err != nil {
if err := DownloadToFile(gzFile, dbUpdateURL); err != nil {
fmt.Println(err)
os.Exit(1)
}

if err := ExtractDatabaseFile(dataDir, gzfile); err != nil {
if err := ExtractDatabaseFile(dataDir, gzFile); err != nil {
fmt.Println(err)
os.Exit(1)
}

if err := os.Remove(gzfile); err != nil {
if err := os.Remove(gzFile); err != nil {
fmt.Println(err)
os.Exit(1)
}
}

// get last-modified header to see if it is an update
func requiresDBUpdate(updateURL string) (bool, error) {
dstFile := path.Join(dataDir, "GeoLite2-Country.mmdb")
if !isFile(dstFile) {
// missing local file, update
return true, nil
}

info, err := os.Stat(dstFile)
if err != nil {
return false, err
}

lastModifiedLocal := info.ModTime()

res, err := http.Head(updateURL)
if err != nil {
return false, err
}

lmHdr := res.Header.Get("last-modified")
if lmHdr == "" {
return false, errors.New("update server returned unexpected response")
}

lastModifiedRemote, err := time.Parse(time.RFC1123, lmHdr)
if err != nil {
return false, err
}

return lastModifiedRemote.After(lastModifiedLocal), nil
}

func getLastModifiedFromHeader(h string) time.Time {
var t time.Time
if h == "" {
return t
}
t, _ = time.Parse(time.RFC1123, h)
return t
}

// ExtractDatabaseFile extracts just the GeoLite2-Country.mmdb from the tar.gz
func ExtractDatabaseFile(dst string, targz string) error {
Verbose(fmt.Sprintf("Opening %s", targz))
func ExtractDatabaseFile(dst string, tarGz string) error {
Verbose(fmt.Sprintf("Opening %s", tarGz))

re, _ := regexp.Compile(`GeoLite2\-Country\.mmdb$`)

r, err := os.Open(targz)
r, err := os.Open(tarGz)
if err != nil {
return err
}
Expand Down Expand Up @@ -106,7 +162,7 @@ func ExtractDatabaseFile(dst string, targz string) error {
outFile := filepath.Join(dst, "GeoLite2-Country.mmdb")

// tmpFile is used to first ensure the extracted database is valid before replacing the previous one
tmpFile, err := ioutil.TempFile("", "testDBFile")
tmpFile, err := os.CreateTemp("", "testDBFile")
if err != nil {
log.Fatal(err)
}
Expand All @@ -125,12 +181,12 @@ func ExtractDatabaseFile(dst string, targz string) error {

Verbose(fmt.Sprintf("Copy %s to %s", tmpFile.Name(), outFile))

input, err := ioutil.ReadFile(tmpFile.Name())
input, err := os.ReadFile(tmpFile.Name())
if err != nil {
return err
}

err = ioutil.WriteFile(outFile, input, 0644)
err = os.WriteFile(outFile, input, 0644)
if err != nil {
return err
}
Expand Down
22 changes: 21 additions & 1 deletion utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,29 @@ func DownloadToFile(filepath string, uri string) error {
return err
}

// IsFile returns if a path is a file
func isFile(path string) bool {
info, err := os.Stat(path)
if os.IsNotExist(err) || !info.Mode().IsRegular() {
return false
}

return true
}

// IsDir returns whether a path is a directory
func isDir(path string) bool {
info, err := os.Stat(path)
if os.IsNotExist(err) || !info.IsDir() {
return false
}

return true
}

// Verbose displays debug information with `-v`
func Verbose(m string) {
if verboseoutput {
if verboseOutput {
fmt.Println(m)
}
}

0 comments on commit be5c67b

Please sign in to comment.