xref: /freebsd/lib/libcasper/libcasper/libcasper.h (revision e0c4386e)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2012-2013 The FreeBSD Foundation
5  * Copyright (c) 2015-2017 Mariusz Zaborski <oshogbo@FreeBSD.org>
6  * All rights reserved.
7  *
8  * This software was developed by Pawel Jakub Dawidek under sponsorship from
9  * the FreeBSD Foundation.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32 
33 #ifndef	_LIBCASPER_H_
34 #define	_LIBCASPER_H_
35 
36 #ifdef HAVE_CASPER
37 #define WITH_CASPER
38 #endif
39 
40 #include <sys/types.h>
41 #include <sys/nv.h>
42 
43 #include <stdlib.h>
44 #include <unistd.h>
45 
46 #define	CASPER_NO_UNIQ	0x00000001
47 
48 #ifndef	_NVLIST_T_DECLARED
49 #define	_NVLIST_T_DECLARED
50 struct nvlist;
51 
52 typedef struct nvlist nvlist_t;
53 #endif
54 
55 #ifndef	_CAP_CHANNEL_T_DECLARED
56 #define	_CAP_CHANNEL_T_DECLARED
57 #ifdef WITH_CASPER
58 struct cap_channel;
59 
60 typedef struct cap_channel cap_channel_t;
61 #define	CASPER_SUPPORT	(1)
62 #else
63 struct cap_channel {
64 	int cch_fd;
65 	int cch_flags;
66 };
67 typedef struct cap_channel cap_channel_t;
68 #define	CASPER_SUPPORT	(0)
69 #endif /* ! WITH_CASPER */
70 #endif /* ! _CAP_CHANNEL_T_DECLARED */
71 
72 __BEGIN_DECLS
73 
74 #ifdef WITH_CASPER
75 int cap_channel_flags(const cap_channel_t *chan);
76 #else
77 static inline int
78 cap_channel_flags(const cap_channel_t *chan)
79 {
80 
81 	return (chan->cch_flags);
82 }
83 #endif
84 
85 static inline int
86 channel_nvlist_flags(const cap_channel_t *chan)
87 {
88 	int flags;
89 
90 	flags = 0;
91 	if ((cap_channel_flags(chan) & CASPER_NO_UNIQ) != 0)
92 		flags |= NV_FLAG_NO_UNIQUE;
93 
94 	return (flags);
95 }
96 
97 /*
98  * The functions opens unrestricted communication channel to Casper.
99  */
100 #ifdef WITH_CASPER
101 cap_channel_t *cap_init(void);
102 #else
103 static inline cap_channel_t *
104 cap_init(void)
105 {
106 	cap_channel_t *chan;
107 
108 	chan = (cap_channel_t *)malloc(sizeof(*chan));
109 	if (chan != NULL) {
110 		chan->cch_fd = -1;
111 	}
112 	return (chan);
113 }
114 #endif
115 
116 /*
117  * The functions to communicate with service.
118  */
119 #ifdef WITH_CASPER
120 cap_channel_t	*cap_service_open(const cap_channel_t *chan, const char *name);
121 int		 cap_service_limit(const cap_channel_t *chan,
122 		    const char * const *names, size_t nnames);
123 #else
124 static inline cap_channel_t *
125 cap_service_open(const cap_channel_t *chan __unused,
126     const char *name __unused)
127 {
128 
129 	return (cap_init());
130 }
131 
132 static inline int
133 cap_service_limit(const cap_channel_t *chan __unused,
134     const char * const *names __unused, size_t nnames __unused)
135 {
136 
137 	return (0);
138 }
139 #endif
140 
141 /*
142  * The function creates cap_channel_t based on the given socket.
143  */
144 #ifdef WITH_CASPER
145 cap_channel_t *cap_wrap(int sock, int flags);
146 #else
147 static inline cap_channel_t *
148 cap_wrap(int sock, int flags)
149 {
150 	cap_channel_t *chan;
151 
152 	chan = cap_init();
153 	if (chan != NULL) {
154 		chan->cch_fd = sock;
155 		chan->cch_flags = flags;
156 	}
157 	return (chan);
158 }
159 #endif
160 
161 /*
162  * The function returns communication socket and frees cap_channel_t.
163  */
164 #ifdef WITH_CASPER
165 int	cap_unwrap(cap_channel_t *chan, int *flags);
166 #else
167 static inline int
168 cap_unwrap(cap_channel_t *chan)
169 {
170 	int fd;
171 
172 	fd = chan->cch_fd;
173 	free(chan);
174 	return (fd);
175 }
176 #endif
177 
178 /*
179  * The function clones the given capability.
180  */
181 #ifdef WITH_CASPER
182 cap_channel_t *cap_clone(const cap_channel_t *chan);
183 #else
184 static inline cap_channel_t *
185 cap_clone(const cap_channel_t *chan)
186 {
187 	cap_channel_t *newchan;
188 
189 	newchan = cap_init();
190 	if (newchan == NULL) {
191 		return (NULL);
192 	}
193 
194 	if (chan->cch_fd == -1) {
195 		newchan->cch_fd = -1;
196 	} else {
197 		newchan->cch_fd = dup(chan->cch_fd);
198 		if (newchan->cch_fd < 0) {
199 			free(newchan);
200 			newchan = NULL;
201 		}
202 	}
203 	newchan->cch_flags = chan->cch_flags;
204 
205 	return (newchan);
206 }
207 #endif
208 
209 /*
210  * The function closes the given capability.
211  */
212 #ifdef WITH_CASPER
213 void	cap_close(cap_channel_t *chan);
214 #else
215 static inline void
216 cap_close(cap_channel_t *chan)
217 {
218 
219 	if (chan->cch_fd >= 0) {
220 		close(chan->cch_fd);
221 	}
222 	free(chan);
223 }
224 #endif
225 
226 /*
227  * The function returns socket descriptor associated with the given
228  * cap_channel_t for use with select(2)/kqueue(2)/etc.
229  */
230 #ifdef WITH_CASPER
231 int	cap_sock(const cap_channel_t *chan);
232 #else
233 #define	cap_sock(chan)	(chan->cch_fd)
234 #endif
235 
236 /*
237  * The function limits the given capability.
238  * It always destroys 'limits' on return.
239  */
240 #ifdef WITH_CASPER
241 int	cap_limit_set(const cap_channel_t *chan, nvlist_t *limits);
242 #else
243 static inline int
244 cap_limit_set(const cap_channel_t *chan __unused,
245     nvlist_t *limits __unused)
246 {
247 
248 	return (0);
249 }
250 #endif
251 
252 /*
253  * The function returns current limits of the given capability.
254  */
255 #ifdef WITH_CASPER
256 int	cap_limit_get(const cap_channel_t *chan, nvlist_t **limitsp);
257 #else
258 static inline int
259 cap_limit_get(const cap_channel_t *chan __unused, nvlist_t **limitsp)
260 {
261 
262 	*limitsp = nvlist_create(channel_nvlist_flags(chan));
263 	return (0);
264 }
265 #endif
266 
267 /*
268  * Function sends nvlist over the given capability.
269  */
270 #ifdef WITH_CASPER
271 int	cap_send_nvlist(const cap_channel_t *chan, const nvlist_t *nvl);
272 #else
273 #define	cap_send_nvlist(chan, nvl)	(0)
274 #endif
275 
276 /*
277  * Function receives nvlist over the given capability.
278  */
279 #ifdef WITH_CASPER
280 nvlist_t *cap_recv_nvlist(const cap_channel_t *chan);
281 #else
282 #define	cap_recv_nvlist(chan)		(nvlist_create(chan->cch_flags))
283 #endif
284 
285 /*
286  * Function sends the given nvlist, destroys it and receives new nvlist in
287  * response over the given capability.
288  */
289 #ifdef WITH_CASPER
290 nvlist_t *cap_xfer_nvlist(const cap_channel_t *chan, nvlist_t *nvl);
291 #else
292 static inline nvlist_t *
293 cap_xfer_nvlist(const cap_channel_t *chan, nvlist_t *nvl)
294 {
295 
296 	nvlist_destroy(nvl);
297 	return (nvlist_create(channel_nvlist_flags(chan)));
298 }
299 #endif
300 
301 __END_DECLS
302 
303 #endif	/* !_LIBCASPER_H_ */
304