1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2018 Mariusz Zaborski <oshogbo@FreeBSD.org>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 * $FreeBSD$
29 */
30
31#ifndef _FILEARGS_H_
32#define	_FILEARGS_H_
33
34#include <sys/cdefs.h>
35#include <sys/dnv.h>
36#include <sys/nv.h>
37
38#include <stdbool.h>
39
40#define	FA_OPEN		1
41#define	FA_LSTAT	2
42#define	FA_REALPATH	4
43
44#ifdef WITH_CASPER
45struct fileargs;
46typedef struct fileargs fileargs_t;
47struct stat;
48
49__BEGIN_DECLS
50
51fileargs_t *fileargs_init(int argc, char *argv[], int flags, mode_t mode,
52    cap_rights_t *rightsp, int operations);
53fileargs_t *fileargs_cinit(cap_channel_t *cas, int argc, char *argv[],
54    int flags, mode_t mode, cap_rights_t *rightsp, int operations);
55fileargs_t *fileargs_initnv(nvlist_t *limits);
56fileargs_t *fileargs_cinitnv(cap_channel_t *cas, nvlist_t *limits);
57int fileargs_lstat(fileargs_t *fa, const char *name, struct stat *sb);
58int fileargs_open(fileargs_t *fa, const char *name);
59char *fileargs_realpath(fileargs_t *fa, const char *pathname,
60    char *reserved_path);
61void fileargs_free(fileargs_t *fa);
62FILE *fileargs_fopen(fileargs_t *fa, const char *name, const char *mode);
63
64fileargs_t *fileargs_wrap(cap_channel_t *chan, int fdflags);
65cap_channel_t *fileargs_unwrap(fileargs_t *fa, int *fdflags);
66
67__END_DECLS
68
69#else
70typedef struct fileargs {
71	int	fa_flags;
72	mode_t	fa_mode;
73} fileargs_t;
74
75static inline fileargs_t *
76fileargs_init(int argc __unused, char *argv[] __unused, int flags, mode_t mode,
77    cap_rights_t *rightsp __unused, int operations __unused) {
78	fileargs_t *fa;
79
80	fa = malloc(sizeof(*fa));
81	if (fa != NULL) {
82		fa->fa_flags = flags;
83		fa->fa_mode = mode;
84	}
85
86	return (fa);
87}
88
89static inline fileargs_t *
90fileargs_cinit(cap_channel_t *cas __unused, int argc, char *argv[], int flags,
91    mode_t mode, cap_rights_t *rightsp, int operations)
92{
93
94	return (fileargs_init(argc, argv, flags, mode, rightsp, operations));
95}
96
97static inline fileargs_t *
98fileargs_initnv(nvlist_t *limits)
99{
100	fileargs_t *fa;
101
102	fa = fileargs_init(0, NULL,
103	    nvlist_get_number(limits, "flags"),
104	    dnvlist_get_number(limits, "mode", 0),
105	    NULL,
106	    nvlist_get_number(limits, "operations"));
107	nvlist_destroy(limits);
108
109	return (fa);
110}
111
112static inline fileargs_t *
113fileargs_cinitnv(cap_channel_t *cas __unused, nvlist_t *limits)
114{
115
116	return (fileargs_initnv(limits));
117}
118
119#define fileargs_lstat(fa, name, sb)						\
120	lstat(name, sb)
121#define	fileargs_open(fa, name)							\
122	open(name, fa->fa_flags, fa->fa_mode)
123#define	fileargs_realpath(fa, pathname, reserved_path)				\
124	realpath(pathname, reserved_path)
125
126static inline
127FILE *fileargs_fopen(fileargs_t *fa, const char *name, const char *mode)
128{
129	(void) fa;
130	return (fopen(name, mode));
131}
132#define	fileargs_free(fa)		(free(fa))
133
134static inline fileargs_t *
135fileargs_wrap(cap_channel_t *chan, int fdflags)
136{
137
138	cap_close(chan);
139	return (fileargs_init(0, NULL, fdflags, 0, NULL, 0));
140}
141
142static inline cap_channel_t *
143fileargs_unwrap(fileargs_t *fa, int *fdflags)
144{
145
146	if (fdflags != NULL) {
147		*fdflags = fa->fa_flags;
148	}
149	fileargs_free(fa);
150	return (cap_init());
151}
152
153#endif
154
155#endif	/* !_FILEARGS_H_ */
156