-
Notifications
You must be signed in to change notification settings - Fork 32
/
main.go
134 lines (115 loc) · 3.19 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package main
import (
"encoding/json"
"fmt"
"log"
"strings"
"sync"
"github.com/mhmdiaa/chronos/v2/modules"
"github.com/mhmdiaa/chronos/v2/pkg/config"
"github.com/mhmdiaa/chronos/v2/pkg/logger"
"github.com/mhmdiaa/chronos/v2/pkg/wayback"
)
func main() {
conf := config.NewConfig()
err := logger.Init(conf.OutputFile)
if err != nil {
log.Fatalf("failed to create the output logger: %v", err)
}
defer logger.Close()
if conf.ListModules {
for _, module := range modules.ModuleRegistry {
fmt.Println(module.Name())
fmt.Printf(" %s\n", module.Description())
}
return
}
if conf.Target == "" {
logger.Error.Fatal("target not specified")
}
logger.Info.Printf("Searching for snapshots...")
snapshotLocationsList, err := wayback.SearchForSnapshots(conf.BaseURL, conf.Target, conf.Filters)
if err != nil {
logger.Error.Fatal(err)
}
logger.Info.Printf("Found %d snapshots\n", len(snapshotLocationsList))
// If no modules are enabled, write snapshot locations and exit
if conf.Modules == "" {
for _, snapshot := range snapshotLocationsList {
j, err := json.Marshal(snapshot)
if err != nil {
logger.Error.Println(err)
continue
}
logger.Output.Println(string(j))
}
return
}
// Set up modules
moduleNames := strings.Split(conf.Modules, ",")
enabledModules := []modules.Module{}
for _, moduleName := range moduleNames {
if module, exists := modules.ModuleRegistry[moduleName]; exists {
enabledModules = append(enabledModules, module)
} else {
logger.Error.Fatalf("Module %s not found", moduleName)
}
}
var moduleWg sync.WaitGroup
moduleWg.Add(len(enabledModules))
outputChan := make(chan modules.ModuleOutput)
var moduleConfig map[string]modules.ModuleConfig
if conf.ConfigFile != "" {
moduleConfig = modules.ParseModuleConfigFile(conf.ConfigFile)
} else {
moduleConfig = modules.ParseModuleOptions(conf.ModuleOptions)
}
for _, module := range enabledModules {
config := moduleConfig[module.Name()]
go module.Process(module.Channel(), outputChan, &moduleWg, config)
}
// Set up snapshot workers
numOfWorkers := conf.Threads
snapshotLocationsChan := make(chan wayback.Snapshot)
snapshotsChan := make(chan wayback.Snapshot)
var snapshotWg sync.WaitGroup
snapshotWg.Add(numOfWorkers)
for i := 0; i < numOfWorkers; i++ {
go wayback.FetchSnapshots(snapshotLocationsChan, snapshotsChan, &snapshotWg)
}
go func() {
for _, location := range snapshotLocationsList {
snapshotLocationsChan <- location
}
close(snapshotLocationsChan)
}()
go func() {
snapshotWg.Wait()
close(snapshotsChan)
}()
// Connect the snapshot channel to the module channels
// Then, close the module channels once the snapshots are completely processed
go func() {
for snapshot := range snapshotsChan {
for _, module := range enabledModules {
module.Channel() <- snapshot
}
}
for _, module := range enabledModules {
close(module.Channel())
}
}()
// Close the output channel once all modules are done writing to it
go func() {
moduleWg.Wait()
close(outputChan)
}()
for output := range outputChan {
j, err := json.Marshal(output)
if err != nil {
logger.Error.Println(err)
continue
}
logger.Output.Println(string(j))
}
}