diff options
| author | Shulhan <ms@kilabit.info> | 2022-05-22 21:29:35 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2022-05-22 21:51:47 +0700 |
| commit | 0b92dbb8463dee31c005c59f67c2bf754a9eae12 (patch) | |
| tree | a95162fc3aaa88ce772f9b7c8b79747c225a0ba8 /blockd.go | |
| parent | 89494ecacdd03426da17def52e35a1a66c9630eb (diff) | |
| download | rescached-0b92dbb8463dee31c005c59f67c2bf754a9eae12.tar.xz | |
all: export and rename the hostsBlock type to Blockd
In the Environment, we have a field HostsBlocks that reference
an unexported type hostsFile.
In order for any package to be able to use this field, we need to
export this type.
While at it, we rename the type from hostsBlock to Blockd to make it
simple and consistent with name.
Diffstat (limited to 'blockd.go')
| -rw-r--r-- | blockd.go | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/blockd.go b/blockd.go new file mode 100644 index 0000000..398bb96 --- /dev/null +++ b/blockd.go @@ -0,0 +1,148 @@ +// SPDX-FileCopyrightText: 2020 M. Shulhan <ms@kilabit.info> +// SPDX-License-Identifier: GPL-3.0-or-later + +package rescached + +import ( + "bytes" + "fmt" + "io" + "log" + "net/http" + "os" + "path/filepath" + "time" +) + +const ( + lastUpdatedFormat = "2006-01-02 15:04:05 MST" +) + +type Blockd struct { + lastUpdated time.Time + + Name string `ini:"::name"` // Derived from hostname in URL. + URL string `ini:"::url"` + + file string + fileDisabled string + LastUpdated string + + IsEnabled bool // True if the hosts file un-hidden in block.d directory. + isFileExist bool // True if the file exist and enabled or disabled. +} + +// disable the hosts block by prefixing the file name with single dot. +func (hb *Blockd) disable() (err error) { + err = os.Rename(hb.file, hb.fileDisabled) + if err != nil { + return fmt.Errorf("disable: %w", err) + } + hb.IsEnabled = false + return nil +} + +// enable the hosts block file by removing the dot prefix from file name. +func (hb *Blockd) enable() (err error) { + if hb.isFileExist { + err = os.Rename(hb.fileDisabled, hb.file) + } else { + err = os.WriteFile(hb.file, []byte(""), 0600) + } + if err != nil { + return fmt.Errorf("enable: %w", err) + } + hb.IsEnabled = true + hb.isFileExist = true + return nil +} + +func (hb *Blockd) init(pathDirBlock string) { + var ( + fi os.FileInfo + err error + ) + + hb.file = filepath.Join(pathDirBlock, hb.Name) + hb.fileDisabled = filepath.Join(pathDirBlock, "."+hb.Name) + + fi, err = os.Stat(hb.file) + if err != nil { + hb.IsEnabled = false + + fi, err = os.Stat(hb.fileDisabled) + if err != nil { + return + } + + hb.isFileExist = true + } else { + hb.IsEnabled = true + hb.isFileExist = true + } + + hb.lastUpdated = fi.ModTime() + hb.LastUpdated = hb.lastUpdated.Format(lastUpdatedFormat) +} + +// isOld will return true if the host file has not been updated since seven +// days. +func (hb *Blockd) isOld() bool { + oneWeek := 7 * 24 * time.Hour + lastWeek := time.Now().Add(-1 * oneWeek) + + return hb.lastUpdated.Before(lastWeek) +} + +func (hb *Blockd) update() (err error) { + if !hb.isOld() { + return nil + } + + var ( + logp = "Blockd.update" + + res *http.Response + body []byte + errClose error + ) + + fmt.Printf("%s %s: updating ...\n", logp, hb.Name) + + err = os.MkdirAll(filepath.Dir(hb.file), 0700) + if err != nil { + return fmt.Errorf("%s %s: %w", logp, hb.Name, err) + } + + res, err = http.Get(hb.URL) + if err != nil { + return fmt.Errorf("%s %s: %w", logp, hb.Name, err) + } + defer func() { + errClose = res.Body.Close() + if errClose != nil { + log.Printf("%s %q: %s", logp, hb.Name, err) + } + }() + + body, err = io.ReadAll(res.Body) + if err != nil { + return fmt.Errorf("%s %q: %w", logp, hb.Name, err) + } + + body = bytes.ReplaceAll(body, []byte("\r\n"), []byte("\n")) + + if hb.IsEnabled { + err = os.WriteFile(hb.file, body, 0644) + } else { + err = os.WriteFile(hb.fileDisabled, body, 0644) + } + if err != nil { + return fmt.Errorf("%s %q: %w", logp, hb.Name, err) + } + + hb.lastUpdated = time.Now() + hb.LastUpdated = hb.lastUpdated.Format(lastUpdatedFormat) + + return nil +} |
