primeiro commit
This commit is contained in:
commit
0aec8da266
10
Makefile
Normal file
10
Makefile
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
.PHONY: build run clean
|
||||||
|
|
||||||
|
build:
|
||||||
|
go build -o bin/file-checksum-monitor ./cmd/file-checksum-monitor
|
||||||
|
|
||||||
|
run: build
|
||||||
|
./bin/file-checksum-monitor
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf bin/
|
67
cmd/file-checksum-monitor/main.go
Normal file
67
cmd/file-checksum-monitor/main.go
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/alpharde/file-checksum-monitor/internal/library"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
dbPath := "libraries.db"
|
||||||
|
manager, err := library.NewLibraryManager(dbPath)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error initializing LibraryManager: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
addCmd := flag.NewFlagSet("add", flag.ExitOnError)
|
||||||
|
scanCmd := flag.NewFlagSet("scan", flag.ExitOnError)
|
||||||
|
compareCmd := flag.NewFlagSet("compare", flag.ExitOnError)
|
||||||
|
|
||||||
|
addName := addCmd.String("name", "", "Name of the library")
|
||||||
|
addDir := addCmd.String("directory", "", "Path to the library directory")
|
||||||
|
|
||||||
|
scanName := scanCmd.String("name", "", "Name of the library to scan")
|
||||||
|
|
||||||
|
compareName := compareCmd.String("name", "", "Name of the library to compare")
|
||||||
|
|
||||||
|
if len(os.Args) < 2 {
|
||||||
|
fmt.Println("Expected 'add', 'scan', or 'compare' subcommands")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch os.Args[1] {
|
||||||
|
case "add":
|
||||||
|
addCmd.Parse(os.Args[2:])
|
||||||
|
if *addName == "" || *addDir == "" {
|
||||||
|
fmt.Println("Usage: add -name <library_name> -directory <directory_path>")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
if err := manager.AddLibrary(*addName, *addDir); err != nil {
|
||||||
|
fmt.Printf("Error adding library: %v\n", err)
|
||||||
|
}
|
||||||
|
case "scan":
|
||||||
|
scanCmd.Parse(os.Args[2:])
|
||||||
|
if *scanName == "" {
|
||||||
|
fmt.Println("Usage: scan -name <library_name>")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
if err := manager.ScanLibrary(*scanName); err != nil {
|
||||||
|
fmt.Printf("Error scanning library: %v\n", err)
|
||||||
|
}
|
||||||
|
case "compare":
|
||||||
|
compareCmd.Parse(os.Args[2:])
|
||||||
|
if *compareName == "" {
|
||||||
|
fmt.Println("Usage: compare -name <library_name>")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
if err := manager.CompareLibrary(*compareName); err != nil {
|
||||||
|
fmt.Printf("Error comparing library: %v\n", err)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
fmt.Println("Unknown subcommand")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
24
internal/library/checksum.go
Normal file
24
internal/library/checksum.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package library
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func calculateChecksum(filePath string) (string, error) {
|
||||||
|
file, err := os.Open(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
data, err := ioutil.ReadAll(file)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
hash := sha256.Sum256(data)
|
||||||
|
return hex.EncodeToString(hash[:]), nil
|
||||||
|
}
|
23
internal/library/database.go
Normal file
23
internal/library/database.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package library
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
)
|
||||||
|
|
||||||
|
func initializeDatabase(db *sql.DB) error {
|
||||||
|
_, err := db.Exec(`
|
||||||
|
CREATE TABLE IF NOT EXISTS libraries (
|
||||||
|
name TEXT PRIMARY KEY,
|
||||||
|
directory TEXT
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS files (
|
||||||
|
library_name TEXT,
|
||||||
|
file_path TEXT,
|
||||||
|
checksum TEXT,
|
||||||
|
failed BOOLEAN DEFAULT FALSE,
|
||||||
|
PRIMARY KEY (library_name, file_path)
|
||||||
|
);
|
||||||
|
`)
|
||||||
|
return err
|
||||||
|
}
|
127
internal/library/manager.go
Normal file
127
internal/library/manager.go
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
package library
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LibraryManager struct {
|
||||||
|
Libraries map[string]string
|
||||||
|
Mutex sync.Mutex
|
||||||
|
db *sql.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLibraryManager(dbPath string) (*LibraryManager, error) {
|
||||||
|
db, err := sql.Open("sqlite3", dbPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := initializeDatabase(db); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &LibraryManager{
|
||||||
|
Libraries: make(map[string]string),
|
||||||
|
db: db,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lm *LibraryManager) AddLibrary(name, directory string) error {
|
||||||
|
lm.Mutex.Lock()
|
||||||
|
defer lm.Mutex.Unlock()
|
||||||
|
|
||||||
|
if _, exists := lm.Libraries[name]; exists {
|
||||||
|
return fmt.Errorf("Library %s already exists", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
lm.Libraries[name] = directory
|
||||||
|
|
||||||
|
_, err := lm.db.Exec("INSERT OR IGNORE INTO libraries (name, directory) VALUES (?, ?)", name, directory)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Library %s added.\n", name)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lm *LibraryManager) ScanLibrary(name string) error {
|
||||||
|
dir, exists := lm.Libraries[name]
|
||||||
|
if !exists {
|
||||||
|
return fmt.Errorf("Library %s does not exist", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
var fileCount int64
|
||||||
|
|
||||||
|
err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !info.Mode().IsRegular() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
checksum, err := calculateChecksum(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = lm.db.Exec("INSERT OR REPLACE INTO files (library_name, file_path, checksum, failed) VALUES (?, ?, ?, FALSE)", name, path, checksum)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
atomic.AddInt64(&fileCount, 1)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Scanned %d files in library %s\n", fileCount, name)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lm *LibraryManager) CompareLibrary(name string) error {
|
||||||
|
rows, err := lm.db.Query("SELECT file_path, checksum FROM files WHERE library_name = ?", name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
var mismatches int
|
||||||
|
|
||||||
|
for rows.Next() {
|
||||||
|
var filePath, storedChecksum string
|
||||||
|
if err := rows.Scan(&filePath, &storedChecksum); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
currentChecksum, err := calculateChecksum(filePath)
|
||||||
|
if err != nil {
|
||||||
|
// Mark the file as failed if it cannot be read
|
||||||
|
_, updateErr := lm.db.Exec("UPDATE files SET failed = TRUE WHERE library_name = ? AND file_path = ?", name, filePath)
|
||||||
|
if updateErr != nil {
|
||||||
|
return fmt.Errorf("error marking file as failed: %v", updateErr)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if currentChecksum != storedChecksum {
|
||||||
|
mismatches++
|
||||||
|
_, err := lm.db.Exec("UPDATE files SET failed = TRUE WHERE library_name = ? AND file_path = ?", name, filePath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Comparison completed. %d mismatches found in library %s\n", mismatches, name)
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user