1 // Copyright 2017 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "policy/resilient_policy_util.h"
6
7 #include <algorithm>
8
9 #include <base/files/file_enumerator.h>
10 #include <base/files/file_util.h>
11 #include <base/strings/string_number_conversions.h>
12 #include <base/strings/string_util.h>
13
14 namespace policy {
15
GetSortedResilientPolicyFilePaths(const base::FilePath & default_policy_path)16 std::map<int, base::FilePath> GetSortedResilientPolicyFilePaths(
17 const base::FilePath& default_policy_path) {
18 std::map<int, base::FilePath> sorted_policy_file_paths;
19 base::FilePath directory = default_policy_path.DirName();
20 if (!base::PathExists(directory))
21 return sorted_policy_file_paths;
22
23 // Iterate the list of files in the folder, identifying the policy files based
24 // on the name. Store in the map the absolute paths.
25 const std::string default_policy_file_name =
26 default_policy_path.BaseName().value();
27 base::FileEnumerator file_iter(directory, false, base::FileEnumerator::FILES);
28 for (base::FilePath child_file = file_iter.Next(); !child_file.empty();
29 child_file = file_iter.Next()) {
30 int index;
31 if (ParseResilientPolicyFilePath(child_file, default_policy_path, &index)) {
32 sorted_policy_file_paths[index] = child_file;
33 }
34 }
35
36 return sorted_policy_file_paths;
37 }
38
ParseResilientPolicyFilePath(const base::FilePath & policy_path,const base::FilePath & default_policy_path,int * index_out)39 bool ParseResilientPolicyFilePath(const base::FilePath& policy_path,
40 const base::FilePath& default_policy_path,
41 int* index_out) {
42 if (!base::StartsWith(policy_path.value(), default_policy_path.value(),
43 base::CompareCase::SENSITIVE)) {
44 return false;
45 }
46
47 if (policy_path == default_policy_path) {
48 *index_out = 0;
49 return true;
50 }
51
52 const std::string extension =
53 policy_path.value().substr(default_policy_path.value().size());
54 if (extension.empty() || extension[0] != '.' ||
55 !base::StringToInt(extension.substr(1), index_out) || *index_out <= 0) {
56 return false;
57 }
58
59 return true;
60 }
61
GetResilientPolicyFilePathForIndex(const base::FilePath & default_policy_path,int index)62 base::FilePath GetResilientPolicyFilePathForIndex(
63 const base::FilePath& default_policy_path,
64 int index) {
65 if (index == 0)
66 return default_policy_path;
67 return base::FilePath(default_policy_path.value() + "." +
68 std::to_string(index));
69 }
70
71 } // namespace policy
72