]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-dns-search-domain.c
Merge pull request #2138 from stefwalter/journal-combine
[thirdparty/systemd.git] / src / resolve / resolved-dns-search-domain.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2015 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include "alloc-util.h"
23 #include "dns-domain.h"
24 #include "resolved-dns-search-domain.h"
25
26 int dns_search_domain_new(
27 Manager *m,
28 DnsSearchDomain **ret,
29 DnsSearchDomainType type,
30 Link *l,
31 const char *name) {
32
33 _cleanup_free_ char *normalized = NULL;
34 DnsSearchDomain *d;
35 int r;
36
37 assert(m);
38 assert((type == DNS_SEARCH_DOMAIN_LINK) == !!l);
39 assert(name);
40
41 r = dns_name_normalize(name, &normalized);
42 if (r < 0)
43 return r;
44
45 if (l) {
46 if (l->n_search_domains >= LINK_SEARCH_DOMAINS_MAX)
47 return -E2BIG;
48 } else {
49 if (m->n_search_domains >= MANAGER_SEARCH_DOMAINS_MAX)
50 return -E2BIG;
51 }
52
53 d = new0(DnsSearchDomain, 1);
54 if (!d)
55 return -ENOMEM;
56
57 d->n_ref = 1;
58 d->manager = m;
59 d->type = type;
60 d->name = normalized;
61 normalized = NULL;
62
63 switch (type) {
64
65 case DNS_SEARCH_DOMAIN_LINK:
66 d->link = l;
67 LIST_APPEND(domains, l->search_domains, d);
68 l->n_search_domains++;
69 break;
70
71 case DNS_SERVER_SYSTEM:
72 LIST_APPEND(domains, m->search_domains, d);
73 m->n_search_domains++;
74 break;
75
76 default:
77 assert_not_reached("Unknown search domain type");
78 }
79
80 d->linked = true;
81
82 if (ret)
83 *ret = d;
84
85 return 0;
86 }
87
88 DnsSearchDomain* dns_search_domain_ref(DnsSearchDomain *d) {
89 if (!d)
90 return NULL;
91
92 assert(d->n_ref > 0);
93 d->n_ref++;
94
95 return d;
96 }
97
98 DnsSearchDomain* dns_search_domain_unref(DnsSearchDomain *d) {
99 if (!d)
100 return NULL;
101
102 assert(d->n_ref > 0);
103 d->n_ref--;
104
105 if (d->n_ref > 0)
106 return NULL;
107
108 free(d->name);
109 free(d);
110
111 return NULL;
112 }
113
114 void dns_search_domain_unlink(DnsSearchDomain *d) {
115 assert(d);
116 assert(d->manager);
117
118 if (!d->linked)
119 return;
120
121 switch (d->type) {
122
123 case DNS_SEARCH_DOMAIN_LINK:
124 assert(d->link);
125 assert(d->link->n_search_domains > 0);
126 LIST_REMOVE(domains, d->link->search_domains, d);
127 d->link->n_search_domains--;
128 break;
129
130 case DNS_SEARCH_DOMAIN_SYSTEM:
131 assert(d->manager->n_search_domains > 0);
132 LIST_REMOVE(domains, d->manager->search_domains, d);
133 d->manager->n_search_domains--;
134 break;
135 }
136
137 d->linked = false;
138
139 dns_search_domain_unref(d);
140 }
141
142 void dns_search_domain_move_back_and_unmark(DnsSearchDomain *d) {
143 DnsSearchDomain *tail;
144
145 assert(d);
146
147 if (!d->marked)
148 return;
149
150 d->marked = false;
151
152 if (!d->linked || !d->domains_next)
153 return;
154
155 switch (d->type) {
156
157 case DNS_SEARCH_DOMAIN_LINK:
158 assert(d->link);
159 LIST_FIND_TAIL(domains, d, tail);
160 LIST_REMOVE(domains, d->link->search_domains, d);
161 LIST_INSERT_AFTER(domains, d->link->search_domains, tail, d);
162 break;
163
164 case DNS_SEARCH_DOMAIN_SYSTEM:
165 LIST_FIND_TAIL(domains, d, tail);
166 LIST_REMOVE(domains, d->manager->search_domains, d);
167 LIST_INSERT_AFTER(domains, d->manager->search_domains, tail, d);
168 break;
169
170 default:
171 assert_not_reached("Unknown search domain type");
172 }
173 }
174
175 void dns_search_domain_unlink_all(DnsSearchDomain *first) {
176 DnsSearchDomain *next;
177
178 if (!first)
179 return;
180
181 next = first->domains_next;
182 dns_search_domain_unlink(first);
183
184 dns_search_domain_unlink_all(next);
185 }
186
187 void dns_search_domain_unlink_marked(DnsSearchDomain *first) {
188 DnsSearchDomain *next;
189
190 if (!first)
191 return;
192
193 next = first->domains_next;
194
195 if (first->marked)
196 dns_search_domain_unlink(first);
197
198 dns_search_domain_unlink_marked(next);
199 }
200
201 void dns_search_domain_mark_all(DnsSearchDomain *first) {
202 if (!first)
203 return;
204
205 first->marked = true;
206 dns_search_domain_mark_all(first->domains_next);
207 }
208
209 int dns_search_domain_find(DnsSearchDomain *first, const char *name, DnsSearchDomain **ret) {
210 DnsSearchDomain *d;
211 int r;
212
213 assert(name);
214 assert(ret);
215
216 LIST_FOREACH(domains, d, first) {
217
218 r = dns_name_equal(name, d->name);
219 if (r < 0)
220 return r;
221 if (r > 0) {
222 *ret = d;
223 return 1;
224 }
225 }
226
227 *ret = NULL;
228 return 0;
229 }