1 /*	$NetBSD: aoutm68k_stat.c,v 1.24 2008/04/28 20:23:41 martin Exp $	*/
2 
3 /*-
4  * Copyright (c) 2000 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Steve C. Woodford.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: aoutm68k_stat.c,v 1.24 2008/04/28 20:23:41 martin Exp $");
34 
35 #if defined(_KERNEL_OPT)
36 #include "opt_compat_netbsd.h"
37 #include "opt_compat_43.h"
38 #endif
39 
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/filedesc.h>
43 #include <sys/mount.h>
44 #include <sys/namei.h>
45 #include <sys/proc.h>
46 #include <sys/stat.h>
47 #include <sys/vfs_syscalls.h>
48 
49 #include <sys/syscall.h>
50 #include <sys/syscallargs.h>
51 
52 #include <compat/sys/stat.h>
53 
54 #include <compat/aoutm68k/aoutm68k_util.h>
55 #include <compat/aoutm68k/aoutm68k_stat.h>
56 #include <compat/aoutm68k/aoutm68k_syscall.h>
57 #include <compat/aoutm68k/aoutm68k_syscallargs.h>
58 
59 #ifdef COMPAT_43
60 static void aoutm68k_stat43_convert(struct stat *, struct aoutm68k_stat43 *);
61 #endif
62 #ifdef COMPAT_12
63 static void aoutm68k_stat12_convert(struct stat *, struct aoutm68k_stat12 *);
64 #endif
65 static void aoutm68k_stat13_convert(struct stat *, struct aoutm68k_stat *);
66 
67 
68 #ifdef COMPAT_43
69 int
aoutm68k_compat_43_sys_stat(struct lwp * l,const struct aoutm68k_compat_43_sys_stat_args * uap,register_t * retval)70 aoutm68k_compat_43_sys_stat(struct lwp *l, const struct aoutm68k_compat_43_sys_stat_args *uap, register_t *retval)
71 {
72 	struct aoutm68k_stat43 ast;
73 	struct stat sb;
74 	int error;
75 
76 	error = do_sys_stat(SCARG(uap, path), FOLLOW, &sb);
77 	if (error)
78 		return error;
79 
80 	aoutm68k_stat43_convert(&sb, &ast);
81 
82 	return copyout(&ast, SCARG(uap, ub), sizeof(ast));
83 }
84 
85 int
aoutm68k_compat_43_sys_fstat(struct lwp * l,const struct aoutm68k_compat_43_sys_fstat_args * uap,register_t * retval)86 aoutm68k_compat_43_sys_fstat(struct lwp *l, const struct aoutm68k_compat_43_sys_fstat_args *uap, register_t *retval)
87 {
88 	struct aoutm68k_stat43 ast;
89 	struct stat sb;
90 	int error;
91 
92 	error = do_sys_fstat(SCARG(uap, fd), &sb);
93 	if (error != 0)
94 		return error;
95 
96 	aoutm68k_stat43_convert(&sb, &ast);
97 
98 	return copyout(&ast, SCARG(uap, sb), sizeof(ast));
99 }
100 
101 int
aoutm68k_compat_43_sys_lstat(struct lwp * l,const struct aoutm68k_compat_43_sys_lstat_args * uap,register_t * retval)102 aoutm68k_compat_43_sys_lstat(struct lwp *l, const struct aoutm68k_compat_43_sys_lstat_args *uap, register_t *retval)
103 {
104 	struct aoutm68k_stat43 ast;
105 	struct stat sb;
106 	int error;
107 
108 	error = do_sys_stat(SCARG(uap, path), NOFOLLOW, &sb);
109 	if (error)
110 		return error;
111 
112 	aoutm68k_stat43_convert(&sb, &ast);
113 
114 	return copyout(&ast, SCARG(uap, ub), sizeof(ast));
115 }
116 #endif /* COMPAT_43 */
117 
118 #ifdef COMPAT_12
119 int
aoutm68k_compat_12_sys_stat(struct lwp * l,const struct aoutm68k_compat_12_sys_stat_args * uap,register_t * retval)120 aoutm68k_compat_12_sys_stat(struct lwp *l, const struct aoutm68k_compat_12_sys_stat_args *uap, register_t *retval)
121 {
122 	struct aoutm68k_stat12 ast;
123 	struct stat sb;
124 	int error;
125 
126 	error = do_sys_stat(SCARG(uap, path), FOLLOW, &sb);
127 	if (error)
128 		return error;
129 
130 	aoutm68k_stat12_convert(&sb, &ast);
131 
132 	return copyout(&ast, SCARG(uap, ub), sizeof(ast));
133 }
134 
135 int
aoutm68k_compat_12_sys_fstat(struct lwp * l,const struct aoutm68k_compat_12_sys_fstat_args * uap,register_t * retval)136 aoutm68k_compat_12_sys_fstat(struct lwp *l, const struct aoutm68k_compat_12_sys_fstat_args *uap, register_t *retval)
137 {
138 	struct aoutm68k_stat12 ast;
139 	struct stat sb;
140 	int error;
141 
142 	error = do_sys_fstat(SCARG(uap, fd), &sb);
143 	if (error != 0)
144 		return error;
145 
146 	aoutm68k_stat12_convert(&sb, &ast);
147 
148 	return copyout(&ast, SCARG(uap, sb), sizeof(ast));
149 }
150 
151 int
aoutm68k_compat_12_sys_lstat(struct lwp * l,const struct aoutm68k_compat_12_sys_lstat_args * uap,register_t * retval)152 aoutm68k_compat_12_sys_lstat(struct lwp *l, const struct aoutm68k_compat_12_sys_lstat_args *uap, register_t *retval)
153 {
154 	struct aoutm68k_stat12 ast;
155 	struct stat sb;
156 	int error;
157 
158 	error = do_sys_stat(SCARG(uap, path), NOFOLLOW, &sb);
159 	if (error)
160 		return error;
161 
162 	aoutm68k_stat12_convert(&sb, &ast);
163 
164 	return copyout(&ast, SCARG(uap, ub), sizeof(ast));
165 }
166 #endif /* COMPAT_12 */
167 
168 int
aoutm68k_sys___stat13(struct lwp * l,const struct aoutm68k_sys___stat13_args * uap,register_t * retval)169 aoutm68k_sys___stat13(struct lwp *l, const struct aoutm68k_sys___stat13_args *uap, register_t *retval)
170 {
171 	struct aoutm68k_stat ast;
172 	struct stat sb;
173 	int error;
174 
175 	error = do_sys_stat(SCARG(uap, path), FOLLOW, &sb);
176 	if (error)
177 		return error;
178 
179 	aoutm68k_stat13_convert(&sb, &ast);
180 
181 	return copyout(&ast, SCARG(uap, ub), sizeof(ast));
182 }
183 
184 int
aoutm68k_sys___fstat13(struct lwp * l,const struct aoutm68k_sys___fstat13_args * uap,register_t * retval)185 aoutm68k_sys___fstat13(struct lwp *l, const struct aoutm68k_sys___fstat13_args *uap, register_t *retval)
186 {
187 	struct aoutm68k_stat ast;
188 	struct stat sb;
189 	int error;
190 
191 	error = do_sys_fstat(SCARG(uap, fd), &sb);
192 	if (error != 0)
193 		return error;
194 
195 	aoutm68k_stat13_convert(&sb, &ast);
196 
197 	return copyout(&ast, SCARG(uap, sb), sizeof(ast));
198 
199 }
200 
201 int
aoutm68k_sys___lstat13(struct lwp * l,const struct aoutm68k_sys___lstat13_args * uap,register_t * retval)202 aoutm68k_sys___lstat13(struct lwp *l, const struct aoutm68k_sys___lstat13_args *uap, register_t *retval)
203 {
204 	struct aoutm68k_stat ast;
205 	struct stat sb;
206 	int error;
207 
208 	error = do_sys_stat(SCARG(uap, path), NOFOLLOW, &sb);
209 	if (error)
210 		return error;
211 
212 	aoutm68k_stat13_convert(&sb, &ast);
213 
214 	return copyout(&ast, SCARG(uap, ub), sizeof(ast));
215 }
216 
217 int
aoutm68k_sys_fhstat(struct lwp * l,const struct aoutm68k_sys_fhstat_args * uap,register_t * retval)218 aoutm68k_sys_fhstat(struct lwp *l, const struct aoutm68k_sys_fhstat_args *uap, register_t *retval)
219 {
220 	struct aoutm68k_stat ast;
221 	struct stat sb;
222 	int error;
223 
224 	error = do_fhstat(l, SCARG(uap, fhp), FHANDLE_SIZE_COMPAT, &sb);
225 	if (error)
226 		return error;
227 
228 	aoutm68k_stat13_convert(&sb, &ast);
229 	return copyout(&sb, SCARG(uap, sb), sizeof(sb));
230 }
231 
232 #ifdef COMPAT_43
233 static void
aoutm68k_stat43_convert(struct stat * st,struct aoutm68k_stat43 * ast)234 aoutm68k_stat43_convert(struct stat *st, struct aoutm68k_stat43 *ast)
235 {
236 
237 	memset(ast, 0, sizeof(*ast));
238 	ast->st_dev = st->st_dev;
239 	ast->st_ino = st->st_ino;
240 	ast->st_mode = st->st_mode;
241 	ast->st_nlink = st->st_nlink;
242 	ast->st_uid = st->st_uid;
243 	ast->st_gid = st->st_gid;
244 	ast->st_rdev = st->st_rdev;
245 	if (st->st_size < (off_t)1 << 32)
246 		ast->st_size = st->st_size;
247 	else
248 		ast->st_size = -2;
249 	ast->st_atimespec.tv_sec = st->st_atimespec.tv_sec;
250 	ast->st_atimespec.tv_nsec = st->st_atimespec.tv_nsec;
251 	ast->st_mtimespec.tv_sec = st->st_mtimespec.tv_sec;
252 	ast->st_mtimespec.tv_nsec = st->st_mtimespec.tv_nsec;
253 	ast->st_ctimespec.tv_sec = st->st_ctimespec.tv_sec;
254 	ast->st_ctimespec.tv_nsec = st->st_ctimespec.tv_nsec;
255 	ast->st_blksize = st->st_blksize;
256 	ast->st_blocks = st->st_blocks;
257 	ast->st_flags = st->st_flags;
258 	ast->st_gen = st->st_gen;
259 }
260 #endif /* COMPAT_43 */
261 
262 #ifdef COMPAT_12
263 static void
aoutm68k_stat12_convert(struct stat * st,struct aoutm68k_stat12 * ast)264 aoutm68k_stat12_convert(struct stat *st, struct aoutm68k_stat12 *ast)
265 {
266 
267 	memset(ast, 0, sizeof(*ast));
268 	ast->st_dev = st->st_dev;
269 	ast->st_ino = st->st_ino;
270 	ast->st_mode = st->st_mode;
271 	ast->st_nlink = st->st_nlink;
272 	ast->st_uid = st->st_uid;
273 	ast->st_gid = st->st_gid;
274 	ast->st_rdev = st->st_rdev;
275 	ast->st_atimespec.tv_sec = st->st_atimespec.tv_sec;
276 	ast->st_atimespec.tv_nsec = st->st_atimespec.tv_nsec;
277 	ast->st_mtimespec.tv_sec = st->st_mtimespec.tv_sec;
278 	ast->st_mtimespec.tv_nsec = st->st_mtimespec.tv_nsec;
279 	ast->st_ctimespec.tv_sec = st->st_ctimespec.tv_sec;
280 	ast->st_ctimespec.tv_nsec = st->st_ctimespec.tv_nsec;
281 	if (st->st_size < (off_t)1 << 32)
282 		ast->st_size = st->st_size;
283 	else
284 		ast->st_size = -2;
285 	ast->st_blocks = st->st_blocks;
286 	ast->st_blksize = st->st_blksize;
287 	ast->st_flags = st->st_flags;
288 	ast->st_gen = st->st_gen;
289 }
290 #endif /* COMPAT_12 */
291 
292 static void
aoutm68k_stat13_convert(struct stat * st,struct aoutm68k_stat * ast)293 aoutm68k_stat13_convert(struct stat *st, struct aoutm68k_stat *ast)
294 {
295 
296 	memset(ast, 0, sizeof(*ast));
297 	ast->st_dev = st->st_dev;
298 	ast->st_ino = st->st_ino;
299 	ast->st_mode = st->st_mode;
300 	ast->st_nlink = st->st_nlink;
301 	ast->st_uid = st->st_uid;
302 	ast->st_gid = st->st_gid;
303 	ast->st_rdev = st->st_rdev;
304 	ast->st_atimespec.tv_sec = st->st_atimespec.tv_sec;
305 	ast->st_atimespec.tv_nsec = st->st_atimespec.tv_nsec;
306 	ast->st_mtimespec.tv_sec = st->st_mtimespec.tv_sec;
307 	ast->st_mtimespec.tv_nsec = st->st_mtimespec.tv_nsec;
308 	ast->st_ctimespec.tv_sec = st->st_ctimespec.tv_sec;
309 	ast->st_ctimespec.tv_nsec = st->st_ctimespec.tv_nsec;
310 	if (st->st_size < (off_t)1 << 32)
311 		ast->st_size = st->st_size;
312 	else
313 		ast->st_size = -2;
314 	ast->st_blocks = st->st_blocks;
315 	ast->st_blksize = st->st_blksize;
316 	ast->st_flags = st->st_flags;
317 	ast->st_gen = st->st_gen;
318 	ast->st_qspare[0] = 0;
319 	ast->st_qspare[1] = 0;
320 }
321