88 {
89 std::unordered_set<std::string> unique;
90
91 for (std::string line : lines) {
92
93 auto start =
line.find_first_not_of(
" \t\r\n");
94 if (start == std::string::npos) continue;
96
97 if (
auto pos =
line.find(
'#'); pos != std::string::npos)
99
100 auto end =
line.find_last_not_of(
" \t\r\n");
101 if (end == std::string::npos) continue;
106 unique.insert(line);
107 continue;
108 }
109
110 std::string host;
113 unique.insert(host);
114 }
115 }
116 }
117
118 if (unique.empty())
119 return false;
120
121 std::vector<std::string> ips(unique.begin(), unique.end());
122 std::sort(ips.begin(), ips.end());
123
124 std::string tmpl = outPath + ".XXXXXX";
125 std::vector<char> path(tmpl.begin(), tmpl.end());
126 path.push_back('\0');
127
128 int fd = mkstemp(path.data());
129 if (fd < 0) return false;
130
131 FILE* f = fdopen(fd, "w");
132 if (!f) { close(fd); return false; }
133
134 for (const auto& ip : ips)
135 fprintf(f, "%s\n", ip.c_str());
136
137 fflush(f);
138 fsync(fd);
139 fclose(f);
140
141 fs::rename(path.data(), outPath);
142 fs::permissions(
143 outPath,
144 fs::perms::owner_read | fs::perms::owner_write,
145 fs::perm_options::replace
146 );
147
148 return true;
149}