func Main()

in cmd/cpe2cve/cpe2cve.go [198:321]


func Main() int {
	var cfg config
	cfg.addFlags()
	provider := flag.String("provider", "", "feed provider. used as a provider name for the feeds passed in through the command line")
	cfgFile := flag.String("config", "", "path to a config file (JSON or TOML); see usage to see how it's configured (pass -v=1 flag for verbose help). Mutually exclusive with command line flags => when used, other flags are ignored")
	flag.Parse()

	var err error
	if *cfgFile != "" {
		// override config from config file
		cfg, err = readConfigFile(*cfgFile)
	}
	if err == nil {
		// add all feeds from cmdline
		cfg.addFeedsFromArgs(*provider, flag.Args()...)
		err = cfg.validate()
	}
	if err != nil {
		flog.Error(err)
		flag.Usage()
	}

	start := time.Now()

	if stats.AreLogged() {
		defer func(start time.Time) {
			stats.TrackTime("run.time", start, time.Second)
			stats.WriteAndLogError()
		}(start)
	}

	flog.V(1).Info("loading NVD feeds...")

	var overrides cvefeed.Dictionary
	dicts := map[string]cvefeed.Dictionary{} // provider -> dictionary
	for provider, files := range cfg.Feeds {
		dict, err := cvefeed.LoadJSONDictionary(files...)
		if err != nil {
			flog.Errorf("failed to load dictionary for provider %s: %v", provider, err)
		}
		dicts[provider] = dict
	}

	allEmpty := true
	for _, dict := range dicts {
		if len(dict) != 0 {
			allEmpty = false
			break
		}
	}
	if allEmpty {
		flog.Error(fmt.Errorf("all dictionaries are empty"))
		return -1
	}

	overrides, err = cvefeed.LoadJSONDictionary(cfg.FeedOverrides...)
	if err != nil {
		flog.Error(err)
		return -1
	}

	flog.V(1).Infof("...done in %v", time.Since(start))

	if len(overrides) != 0 {
		start = time.Now()
		flog.V(1).Info("applying overrides...")
		for _, dict := range dicts {
			dict.Override(overrides)
		}
		flog.V(1).Infof("...done in %v", time.Since(start))
	}

	caches := map[string]*cvefeed.Cache{}
	for provider, dict := range dicts {
		caches[provider] = cvefeed.NewCache(dict).SetRequireVersion(cfg.RequireVersion).SetMaxSize(cfg.CacheSize)
	}

	if cfg.IndexDict {
		start = time.Now()
		flog.V(1).Info("indexing dictionaries...")
		for provider, cache := range caches {
			cache.Idx = cvefeed.NewIndex(dicts[provider])
			if flog.V(2) {
				var named, total int
				for k, v := range cache.Idx {
					if k != wfn.Any {
						named += len(v)
					}
					total += len(v)
				}
				flog.Infof("%d out of %d records are named", named, total)
			}
		}
		flog.V(1).Infof("...done in %v", time.Since(start))
	}

	if cfg.CPUProfile != "" {
		f, err := os.Create(cfg.CPUProfile)
		if err != nil {
			flog.Error(err)
			return 1
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

	done := processInput(os.Stdin, os.Stdout, caches, cfg)

	if cfg.MemoryProfile != "" {
		f, err := os.Create(cfg.MemoryProfile)
		if err != nil {
			flog.Error(err)
			return 1
		}
		runtime.GC()
		if err = pprof.WriteHeapProfile(f); err != nil {
			flog.Errorf("couldn't write heap profile: %v", err)
		}
		f.Close()
	}

	<-done
	return 0
}