xref: /freebsd/lib/libcasper/libcasper/libcasper.h (revision 0957b409)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
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  * $FreeBSD$
33  */
34 
35 #ifndef	_LIBCASPER_H_
36 #define	_LIBCASPER_H_
37 
38 #ifdef HAVE_CASPER
39 #define WITH_CASPER
40 #endif
41 
42 #include <sys/types.h>
43 #include <sys/nv.h>
44 
45 #include <stdlib.h>
46 #include <unistd.h>
47 
48 #define	CASPER_NO_UNIQ	0x00000001
49 
50 #ifndef	_NVLIST_T_DECLARED
51 #define	_NVLIST_T_DECLARED
52 struct nvlist;
53 
54 typedef struct nvlist nvlist_t;
55 #endif
56 
57 #ifndef	_CAP_CHANNEL_T_DECLARED
58 #define	_CAP_CHANNEL_T_DECLARED
59 #ifdef WITH_CASPER
60 struct cap_channel;
61 
62 typedef struct cap_channel cap_channel_t;
63 #define	CASPER_SUPPORT	(1)
64 #else
65 struct cap_channel {
66 	int cch_fd;
67 	int cch_flags;
68 };
69 typedef struct cap_channel cap_channel_t;
70 #define	CASPER_SUPPORT	(0)
71 #endif /* ! WITH_CASPER */
72 #endif /* ! _CAP_CHANNEL_T_DECLARED */
73 
74 __BEGIN_DECLS
75 
76 #ifdef WITH_CASPER
77 int cap_channel_flags(const cap_channel_t *chan);
78 #else
79 static inline int
80 cap_channel_flags(const cap_channel_t *chan)
81 {
82 
83 	return (chan->cch_flags);
84 }
85 #endif
86 
87 static inline int
88 channel_nvlist_flags(const cap_channel_t *chan)
89 {
90 	int flags;
91 
92 	flags = 0;
93 	if ((cap_channel_flags(chan) & CASPER_NO_UNIQ) != 0)
94 		flags |= NV_FLAG_NO_UNIQUE;
95 
96 	return (flags);
97 }
98 
99 /*
100  * The functions opens unrestricted communication channel to Casper.
101  */
102 #ifdef WITH_CASPER
103 cap_channel_t *cap_init(void);
104 #else
105 static inline cap_channel_t *
106 cap_init(void)
107 {
108 	cap_channel_t *chan;
109 
110 	chan = (cap_channel_t *)malloc(sizeof(*chan));
111 	if (chan != NULL) {
112 		chan->cch_fd = -1;
113 	}
114 	return (chan);
115 }
116 #endif
117 
118 /*
119  * The functions to communicate with service.
120  */
121 #ifdef WITH_CASPER
122 cap_channel_t	*cap_service_open(const cap_channel_t *chan, const char *name);
123 int		 cap_service_limit(const cap_channel_t *chan,
124 		    const char * const *names, size_t nnames);
125 #else
126 #define	cap_service_open(chan, name)		(cap_init())
127 #define	cap_service_limit(chan, names, nnames)	(0)
128 #endif
129 
130 /*
131  * The function creates cap_channel_t based on the given socket.
132  */
133 #ifdef WITH_CASPER
134 cap_channel_t *cap_wrap(int sock, int flags);
135 #else
136 static inline cap_channel_t *
137 cap_wrap(int sock, int flags)
138 {
139 	cap_channel_t *chan;
140 
141 	chan = cap_init();
142 	if (chan != NULL) {
143 		chan->cch_fd = sock;
144 		chan->cch_flags = flags;
145 	}
146 	return (chan);
147 }
148 #endif
149 
150 /*
151  * The function returns communication socket and frees cap_channel_t.
152  */
153 #ifdef WITH_CASPER
154 int	cap_unwrap(cap_channel_t *chan, int *flags);
155 #else
156 static inline int
157 cap_unwrap(cap_channel_t *chan)
158 {
159 	int fd;
160 
161 	fd = chan->cch_fd;
162 	free(chan);
163 	return (fd);
164 }
165 #endif
166 
167 /*
168  * The function clones the given capability.
169  */
170 #ifdef WITH_CASPER
171 cap_channel_t *cap_clone(const cap_channel_t *chan);
172 #else
173 static inline cap_channel_t *
174 cap_clone(const cap_channel_t *chan)
175 {
176 	cap_channel_t *newchan;
177 
178 	newchan = cap_init();
179 	if (newchan == NULL) {
180 		return (NULL);
181 	}
182 
183 	if (chan->cch_fd == -1) {
184 		newchan->cch_fd = -1;
185 	} else {
186 		newchan->cch_fd = dup(chan->cch_fd);
187 		if (newchan->cch_fd < 0) {
188 			free(newchan);
189 			newchan = NULL;
190 		}
191 	}
192 	newchan->cch_flags = chan->cch_flags;
193 
194 	return (newchan);
195 }
196 #endif
197 
198 /*
199  * The function closes the given capability.
200  */
201 #ifdef WITH_CASPER
202 void	cap_close(cap_channel_t *chan);
203 #else
204 static inline void
205 cap_close(cap_channel_t *chan)
206 {
207 
208 	if (chan->cch_fd >= 0) {
209 		close(chan->cch_fd);
210 	}
211 	free(chan);
212 }
213 #endif
214 
215 /*
216  * The function returns socket descriptor associated with the given
217  * cap_channel_t for use with select(2)/kqueue(2)/etc.
218  */
219 #ifdef WITH_CASPER
220 int	cap_sock(const cap_channel_t *chan);
221 #else
222 #define	cap_sock(chan)	(chan->cch_fd)
223 #endif
224 
225 /*
226  * The function limits the given capability.
227  * It always destroys 'limits' on return.
228  */
229 #ifdef WITH_CASPER
230 int	cap_limit_set(const cap_channel_t *chan, nvlist_t *limits);
231 #else
232 #define	cap_limit_set(chan, limits)	(0)
233 #endif
234 
235 /*
236  * The function returns current limits of the given capability.
237  */
238 #ifdef WITH_CASPER
239 int	cap_limit_get(const cap_channel_t *chan, nvlist_t **limitsp);
240 #else
241 static inline int
242 cap_limit_get(const cap_channel_t *chan __unused, nvlist_t **limitsp)
243 {
244 
245 	*limitsp = nvlist_create(channel_nvlist_flags(chan));
246 	return (0);
247 }
248 #endif
249 
250 /*
251  * Function sends nvlist over the given capability.
252  */
253 #ifdef WITH_CASPER
254 int	cap_send_nvlist(const cap_channel_t *chan, const nvlist_t *nvl);
255 #else
256 #define	cap_send_nvlist(chan, nvl)	(0)
257 #endif
258 
259 /*
260  * Function receives nvlist over the given capability.
261  */
262 #ifdef WITH_CASPER
263 nvlist_t *cap_recv_nvlist(const cap_channel_t *chan);
264 #else
265 #define	cap_recv_nvlist(chan)		(nvlist_create(chan->cch_flags))
266 #endif
267 
268 /*
269  * Function sends the given nvlist, destroys it and receives new nvlist in
270  * response over the given capability.
271  */
272 #ifdef WITH_CASPER
273 nvlist_t *cap_xfer_nvlist(const cap_channel_t *chan, nvlist_t *nvl);
274 #else
275 static inline nvlist_t *
276 cap_xfer_nvlist(const cap_channel_t *chan, nvlist_t *nvl)
277 {
278 
279 	nvlist_destroy(nvl);
280 	return (nvlist_create(channel_nvlist_flags(chan)));
281 }
282 #endif
283 
284 __END_DECLS
285 
286 #endif	/* !_LIBCASPER_H_ */
287