This file is indexed.

/usr/include/facter/facts/collection.hpp is in facter-dev 3.10.0-4.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
/**
 * @file
 * Declares the fact collection.
 */
#pragma once

#include "resolver.hpp"
#include "value.hpp"
#include "external/resolver.hpp"
#include "../export.h"
#include <list>
#include <map>
#include <set>
#include <unordered_map>
#include <vector>
#include <string>
#include <memory>
#include <functional>
#include <stdexcept>
#include <iostream>

namespace facter { namespace facts {

    /**
     * The supported output format for the fact collection.
     */
    enum class format
    {
        /**
         * Use ruby "hash" as the format (default).
         */
        hash,
        /**
         * Use JSON as the format.
         */
        json,
        /**
         * Use YAML as the format.
         */
        yaml
    };

    namespace {
        /**
         * Stream adapter for using with rapidjson
         */
        struct stream_adapter
        {
            typedef char Ch;
            /**
             * Constructs an adapter for use with rapidjson around the given stream.
             * @param stream an output stream to which JSON will be written
             */
            explicit stream_adapter(std::ostream& stream) : _stream(stream)
            {
            }

            /**
             * Adds a character to the stream.
             * @param c the char to add
             */
            void Put(char c)
            {
                _stream << c;
            }

            /**
             * Flushes the stream.
             */
            void Flush()
            {
                _stream.flush();
            }

         private:
            std::ostream& _stream;
        };
    }

    /**
     * Represents the fact collection.
     * The fact collection is responsible for resolving and storing facts.
     */
    struct LIBFACTER_EXPORT collection
    {
        /**
         * Inherent "has_weight" value for external facts.
         */
        constexpr static size_t external_fact_weight = 10000;

        /**
         * Constructs a fact collection.
         * @param blocklist the names of resolvers that should not be resolved
         * @param ttls a map of resolver names to cache intervals (times-to-live)
         *        for the facts they resolve
         * @param ignore_cache true if the cache should not be consulted when resolving facts
         */
        collection(std::set<std::string> const& blocklist = std::set<std::string>(),
                   std::unordered_map<std::string, int64_t> const& ttls = std::unordered_map<std::string, int64_t>{},
                   bool ignore_cache = false);

        /**
         * Destructor for fact collection.
         */
        ~collection();

        /**
         * Prevents the fact collection from being copied.
         */
        collection(collection const&) = delete;

        /**
         * Prevents the fact collection from being copied.
         * @returns Returns this fact collection.
         */
        collection& operator=(collection const&) = delete;

        /**
         * Moves the given fact collection into this fact collection.
         * @param other The fact collection to move into this fact collection.
         */
        // Visual Studio 12 still doesn't allow default for move constructor.
        collection(collection&& other);

        /**
         * Moves the given fact collection into this fact collection.
         * @param other The fact collection to move into this fact collection.
         * @return Returns this fact collection.
         */
        // Visual Studio 12 still doesn't allow default for move assignment.
        collection& operator=(collection&& other);

        /**
         * Adds the default facts to the collection.
         * @param include_ruby_facts Whether or not to include facts which require Ruby in the collection.
         */
        void add_default_facts(bool include_ruby_facts);

        /**
         * Adds a resolver to the fact collection.
         * The last resolver that was added for a particular name or pattern will "win" resolution.
         * @param res The resolver to add to the fact collection.
         */
        void add(std::shared_ptr<resolver> const& res);

        /**
         * Adds a fact to the fact collection.
         * @param name The name of the fact.
         * @param value The value of the fact.
         */
        void add(std::string name, std::unique_ptr<value> value);

        /**
         * Adds a custom fact to the fact collection.
         * @param name The name of the fact.
         * @param value The value of the fact.
         * @param weight The weight of the fact.
         */
        void add_custom(std::string name, std::unique_ptr<value> value, size_t weight);

        /**
         * Adds an external fact to the fact collection.
         * @param name The name of the fact.
         * @param value The value of the fact.
         */
        void add_external(std::string name, std::unique_ptr<value> value);

        /**
         * Adds external facts to the fact collection.
         * @param directories The directories to search for external facts.  If empty, the default search paths will be used.
         */
        void add_external_facts(std::vector<std::string> const& directories = {});

        /**
         * Adds facts defined via "FACTER_xyz" environment variables.
         * @param callback The callback that is called with the name of each fact added from the environment.
         */
        void add_environment_facts(std::function<void(std::string const&)> callback = nullptr);

        /**
         * Removes a resolver from the fact collection.
         * @param res The resolver to remove from the fact collection.
         */
        void remove(std::shared_ptr<resolver> const& res);

        /**
         * Removes a fact by name.
         * @param name The name of the fact to remove.
         */
        void remove(std::string const& name);

        /**
         * Clears the entire fact collection.
         * This will remove all built-in facts and resolvers from the fact collection.
         */
        void clear();

        /**
         * Checks to see if the fact collection is empty.
         * All facts will be resolved to determine if the collection is empty.
         * @return Returns true if the fact collection is empty or false if it is not.
         */
        bool empty();

        /**
         * Gets the count of facts in the fact collection.
         * All facts will be resolved to determine the size of the collection.
         * @return Returns the number of facts in the fact collection.
         */
        size_t size();

        /**
         * Gets a fact value by name.
         * @tparam T The expected type of the value.
         * @param name The name of the fact to get the value of.
         * @return Returns a pointer to the fact value or nullptr if the fact is not in the fact collection or the value is not the expected type.
         */
        template <typename T = value>
        T const* get(std::string const& name)
        {
            return dynamic_cast<T const*>(get_value(name));
        }

        /**
        * Gets a fact value by name without resolving the fact.
        * @tparam T The expected type of the value.
        * @param name The name of the fact to get the value of.
        * @return Returns a pointer to the fact value or nullptr if the fact is not resolved or the value is not the expected type.
        */
        template <typename T = value>
        T const* get_resolved(std::string const& name) const
        {
            // Lookup the fact without resolving
            auto it = _facts.find(name);
            return dynamic_cast<T const*>(it == _facts.end() ? nullptr : it->second.get());
        }

        /**
         * Gets a fact value by name
         * @param name The name of the fact to get the value of.
         * @return Returns a pointer to the fact value or nullptr if the fact is not in the fact collection.
         */
        value const* operator[](std::string const& name);

        /**
         * Query the collection.
         * @tparam T The expected type of the value.
         * @param query The query to run.
         * @return Returns the result of the query or nullptr if the query returned no value.
         */
        template <typename T = value>
        T const* query(std::string const& query)
        {
            return dynamic_cast<T const*>(query_value(query, false));
        }

        /**
         * Enumerates all facts in the collection.
         * All facts will be resolved prior to enumeration.
         * @param func The callback function called for each fact in the collection.
         */
        void each(std::function<bool(std::string const&, value const*)> func);

        /**
         * Writes the contents of the fact collection to the given stream, hiding legacy facts.
         * All facts will be resolved prior to writing.
         * @param stream The stream to write the facts to.
         * @param fmt The output format to use.
         * @param queries The set of queries to filter the output to. If empty, all facts will be output.
         * @return Returns the stream being written to.
         */
        std::ostream& write(std::ostream& stream, format fmt = format::hash, std::set<std::string> const& queries = std::set<std::string>());

        /**
         * Writes the contents of the fact collection to the given stream.
         * All facts will be resolved prior to writing.
         * @param stream The stream to write the facts to.
         * @param fmt The output format to use.
         * @param queries The set of queries to filter the output to. If empty, all facts will be output.
         * @param show_legacy Show legacy facts when querying all facts.
         * @param strict_errors Report additional error cases
         * @return Returns the stream being written to.
         */
        std::ostream& write(std::ostream& stream, format fmt, std::set<std::string> const& queries, bool show_legacy, bool strict_errors);

        /**
         * Resolves all facts in the collection.
         */
        void resolve_facts();

        /**
         * Returns the names of all the resolvers currently in the collection,
         * along with their associated facts. The group names are used to allow
         * caching of those facts.
         * @return a map of group names to their associated fact names
         */
        std::map<std::string, std::vector<std::string>> get_fact_groups();

        /**
         * Returns the names of all blockable resolvers currently in the collection,
         * along with their associated facts. The group names are used to allow
         * blocking of those facts.
         * @return a map of blockable group names to their associated fact names
         */
        std::map<std::string, std::vector<std::string>> get_blockable_fact_groups();

     protected:
        /**
         *  Gets external fact directories for the current platform.
         *  @return A list of file paths that will be searched for external facts.
         */
        virtual std::vector<std::string> get_external_fact_directories() const;

     private:
        LIBFACTER_NO_EXPORT void resolve_fact(std::string const& name);
        LIBFACTER_NO_EXPORT value const* get_value(std::string const& name);
        LIBFACTER_NO_EXPORT value const* query_value(std::string const& query, bool strict_errors);
        LIBFACTER_NO_EXPORT value const* lookup(value const* value, std::string const& name, bool strict_errors);
        LIBFACTER_NO_EXPORT void write_hash(std::ostream& stream, std::set<std::string> const& queries, bool show_legacy, bool strict_errors);
        LIBFACTER_NO_EXPORT void write_json(std::ostream& stream, std::set<std::string> const& queries, bool show_legacy, bool strict_errors);
        LIBFACTER_NO_EXPORT void write_yaml(std::ostream& stream, std::set<std::string> const& queries, bool show_legacy, bool strict_errors);
        LIBFACTER_NO_EXPORT void add_common_facts(bool include_ruby_facts);
        LIBFACTER_NO_EXPORT bool add_external_facts_dir(std::vector<std::unique_ptr<external::resolver>> const& resolvers, std::string const& directory, bool warn);
        LIBFACTER_NO_EXPORT bool try_block(std::shared_ptr<resolver> const& res);
        LIBFACTER_NO_EXPORT void resolve(std::shared_ptr<resolver> const& res);

        // Platform specific members
        LIBFACTER_NO_EXPORT void add_platform_facts();
        LIBFACTER_NO_EXPORT std::vector<std::unique_ptr<external::resolver>> get_external_resolvers();

        std::map<std::string, std::unique_ptr<value>> _facts;
        std::list<std::shared_ptr<resolver>> _resolvers;
        std::multimap<std::string, std::shared_ptr<resolver>> _resolver_map;
        std::list<std::shared_ptr<resolver>> _pattern_resolvers;
        std::set<std::string> _blocklist;
        std::unordered_map<std::string, int64_t> _ttls;
        bool _ignore_cache;
    };

}}  // namespace facter::facts