// Workers receive file names on 'in', scan them, and output the results on 'out' func worker(in, cnt chan string, done chan bool, engine *clamav.Engine) { for path := range in { if *debug { log.Printf("scanning %s", path) } if *scan { virus, _, err := engine.ScanFileCb(path, clamav.ScanStdopt|clamav.ScanAllmatches, path) if virus != "" { log.Printf("virus found in %s: %s", path, virus) } else if err != nil { log.Printf("error scanning %s: %v", path, err) } } } done <- true }
func main() { var engine *clamav.Engine flag.Usage = usage flag.Parse() if *clamavversion { fmt.Println(clamav.Retver()) os.Exit(0) } args := flag.Args() if len(args) == 0 && !*testmap { fmt.Fprintln(os.Stderr, "error: missing path\n") usage() } runtime.GOMAXPROCS(*cpus) if *scan { log.Println("initializing ClamAV database...") engine = initClamAV() } if *testmap { fmap := clamav.OpenMemory(eicar) defer clamav.CloseMemory(fmap) virus, _, err := engine.ScanMapCb(fmap, clamav.ScanStdopt|clamav.ScanAllmatches, "eicar memorytest") if err != nil { log.Printf("error scanning in-memory: %v\n", err) } log.Printf("in-memory scan result: %s (eicar)\n", virus) return } in := make(chan string, 1024) cnt := make(chan string, 1024) out := make(chan string, 1024) done := make(chan bool, *workers) log.Println("scan starting...") if *clamavdebug { clamav.Debug() } for i := 0; i < *workers; i++ { go worker(cnt, out, done, engine) } go counter(in, cnt) for _, v := range args { walker(v, in) } close(in) for i := 0; i < *workers; i++ { <-done } log.Println("scan completed...") }