1 // GoCheese -- Python private package repository and caching proxy
2 // Copyright (C) 2019-2024 Sergey Matveev <stargrave@stargrave.org>
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, version 3 of the License.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program. If not, see <http://www.gnu.org/licenses/>.
34 func checker(jobs chan string, isGood *bool, workers *sync.WaitGroup) {
35 hasherBLAKE2b256 := blake2b256New()
36 hasherSHA256 := sha256.New()
37 digestBuf := make([]byte, 32)
43 for fn := range jobs {
46 fmt.Println("ERR", fn, err)
51 digest, err = os.ReadFile(fn + "." + HashAlgoBLAKE2b256)
53 if !errors.Is(err, fs.ErrNotExist) {
54 fmt.Println("ERR", fn+"."+HashAlgoBLAKE2b256, err)
59 hasherBLAKE2b256.Reset()
61 _, err = io.Copy(hasherBLAKE2b256, &br)
62 fd.Seek(0, io.SeekStart)
64 fmt.Println("ERR", fn+"."+HashAlgoBLAKE2b256, err)
68 if bytes.Equal(hasherBLAKE2b256.Sum(digestBuf[:0]), digest) {
69 fmt.Println("GOOD", fn+"."+HashAlgoBLAKE2b256)
71 fmt.Println("BAD", fn+"."+HashAlgoBLAKE2b256)
76 digest, err = os.ReadFile(fn + "." + HashAlgoSHA256)
78 if !errors.Is(err, fs.ErrNotExist) {
79 fmt.Println("ERR", fn+"."+HashAlgoSHA256, err)
87 _, err = io.Copy(hasherSHA256, &br)
90 fmt.Println("ERR", fn+"."+HashAlgoBLAKE2b256, err)
94 if bytes.Equal(hasherSHA256.Sum(digestBuf[:0]), digest) {
95 fmt.Println("GOOD", fn+"."+HashAlgoSHA256)
97 fmt.Println("BAD", fn+"."+HashAlgoSHA256)
103 func goodIntegrity() bool {
105 jobs := make(chan string, 1<<10)
106 var workers sync.WaitGroup
107 workers.Add(runtime.NumCPU())
108 for i := 0; i < runtime.NumCPU(); i++ {
109 go checker(jobs, &isGood, &workers)
111 fd, err := os.Open(Root)
115 dirs, err := fd.ReadDir(0)
120 for _, dir := range dirs {
121 fd, err = os.Open(filepath.Join(Root, dir.Name()))
125 files, err := fd.ReadDir(0)
130 for _, file := range files {
131 for _, ext := range KnownExts {
132 if strings.HasSuffix(file.Name(), ext) {
133 jobs <- filepath.Join(Root, dir.Name(), file.Name())