@@ -51,6 +51,7 @@ func (r *Runner) EnumerateSingleQueryWithCtx(ctx context.Context, query string,
5151 now := time .Now ()
5252 results := r .agent .EnumerateQueriesWithCtx (ctx , query , r .options .Proxy , r .options .RateLimit , r .options .Timeout , time .Duration (r .options .MaxEnumerationTime )* time .Minute , agent .WithCustomRateLimit (r .rateLimit ))
5353
54+ outputWriter := NewOutputWriter (r .options .JSON )
5455 wg := & sync.WaitGroup {}
5556 wg .Add (1 )
5657 // Create a unique map for filtering duplicate domains out
@@ -82,7 +83,9 @@ func (r *Runner) EnumerateSingleQueryWithCtx(ctx context.Context, query string,
8283
8384 // Log the verbose message about the found domain per source
8485 if _ , ok := sourceMap [domain ][result.Source ]; ! ok {
85- gologger .Verbose ().Label (result .Source ).Msg (domain )
86+ if r .options .Verbose {
87+ gologger .Verbose ().Label (result .Source ).Msg (domain )
88+ }
8689 }
8790
8891 sourceMap [domain ][result.Source ] = struct {}{}
@@ -97,10 +100,27 @@ func (r *Runner) EnumerateSingleQueryWithCtx(ctx context.Context, query string,
97100
98101 uniqueMap [domain ] = hostEntry
99102 // If the user asked to remove wildcard then send on the resolve
100- // queue. Otherwise, if mode is not verbose print the results on
101- // the screen as they are discovered.
103+ // queue. Otherwise, output results immediately as they are discovered.
102104 if r .options .RemoveWildcard {
103105 resolutionPool .Tasks <- hostEntry
106+ } else {
107+ for _ , writer := range writers {
108+ var err error
109+ if r .options .CaptureSources {
110+ hostSourceMap := map [string ]map [string ]struct {}{domain : sourceMap [domain ]}
111+ err = outputWriter .WriteSourceHost (query , hostSourceMap , writer )
112+ } else {
113+ hostMap := map [string ]resolve.HostEntry {domain : hostEntry }
114+ err = outputWriter .WriteHost (query , hostMap , writer )
115+ }
116+ if err != nil {
117+ gologger .Error ().Msgf ("Could not write result for %s: %s\n " , domain , err )
118+ }
119+ }
120+ // Call result callback if set
121+ if r .options .ResultCallback != nil {
122+ r .options .ResultCallback (& hostEntry )
123+ }
104124 }
105125 }
106126 }
@@ -113,7 +133,7 @@ func (r *Runner) EnumerateSingleQueryWithCtx(ctx context.Context, query string,
113133 }()
114134
115135 // If the user asked to remove wildcards, listen from the results
116- // queue and write to the map. At the end, print the found results to the screen
136+ // queue and write results in real-time
117137 foundResults := make (map [string ]resolve.Result )
118138 if r .options .RemoveWildcard {
119139 // Process the results coming from the resolutions pool
@@ -122,36 +142,30 @@ func (r *Runner) EnumerateSingleQueryWithCtx(ctx context.Context, query string,
122142 case resolve .Error :
123143 gologger .Warning ().Msgf ("Could not resolve host: %s\n " , result .Error )
124144 case resolve .Subdomain :
125- // Add the found domain to a map.
145+ // Add the found domain to a map and output immediately
126146 if _ , ok := foundResults [result .Host ]; ! ok {
127147 foundResults [result .Host ] = result
148+ for _ , writer := range writers {
149+ var err error
150+ if r .options .HostIP {
151+ resultMap := map [string ]resolve.Result {result .Host : result }
152+ err = outputWriter .WriteHostIP (query , resultMap , writer )
153+ } else {
154+ resultMap := map [string ]resolve.Result {result .Host : result }
155+ err = outputWriter .WriteHostNoWildcard (query , resultMap , writer )
156+ }
157+ if err != nil {
158+ gologger .Error ().Msgf ("Could not write result for %s: %s\n " , result .Host , err )
159+ }
160+ }
161+ if r .options .ResultCallback != nil {
162+ r .options .ResultCallback (& resolve.HostEntry {Query : query , Host : result .Host , Source : result .Source })
163+ }
128164 }
129165 }
130166 }
131167 }
132168 wg .Wait ()
133- outputWriter := NewOutputWriter (r .options .JSON )
134- // Now output all results in output writers
135- var err error
136- for _ , writer := range writers {
137- if r .options .HostIP {
138- err = outputWriter .WriteHostIP (query , foundResults , writer )
139- } else {
140- if r .options .RemoveWildcard {
141- err = outputWriter .WriteHostNoWildcard (query , foundResults , writer )
142- } else {
143- if r .options .CaptureSources {
144- err = outputWriter .WriteSourceHost (query , sourceMap , writer )
145- } else {
146- err = outputWriter .WriteHost (query , uniqueMap , writer )
147- }
148- }
149- }
150- if err != nil {
151- gologger .Error ().Msgf ("Could not write results for %s: %s\n " , query , err )
152- return err
153- }
154- }
155169
156170 // Show found domain count in any case.
157171 duration := durafmt .Parse (time .Since (now )).LimitFirstN (maxNumCount ).String ()
@@ -161,18 +175,6 @@ func (r *Runner) EnumerateSingleQueryWithCtx(ctx context.Context, query string,
161175 } else {
162176 numberOfDomains = len (uniqueMap )
163177 }
164-
165- if r .options .ResultCallback != nil {
166- if r .options .RemoveWildcard {
167- for host , result := range foundResults {
168- r .options .ResultCallback (& resolve.HostEntry {Query : host , Host : result .Host , Source : result .Source })
169- }
170- } else {
171- for _ , v := range uniqueMap {
172- r .options .ResultCallback (& v )
173- }
174- }
175- }
176178 gologger .Info ().Msgf ("Found %d domains for %s in %s\n " , numberOfDomains , query , duration )
177179
178180 if r .options .Statistics {
0 commit comments