1 /* $MirOS: src/sys/compat/openbsd/openbsd_stat.c,v 1.3 2008/11/08 23:04:13 tg Exp $ */
2 
3 /*-
4  * Copyright (c) 2004
5  *	Thorsten "mirabilos" Glaser <tg@mirbsd.org>
6  *
7  * Licensee is hereby permitted to deal in this work without restric-
8  * tion, including unlimited rights to use, publicly perform, modify,
9  * merge, distribute, sell, give away or sublicence, provided all co-
10  * pyright notices above, these terms and the disclaimer are retained
11  * in all redistributions or reproduced in accompanying documentation
12  * or other materials provided with binary redistributions.
13  *
14  * All advertising materials mentioning features or use of this soft-
15  * ware must display the following acknowledgement:
16  *	This product includes material provided by Thorsten Glaser.
17  *
18  * Licensor offers the work "AS IS" and WITHOUT WARRANTY of any kind,
19  * express, or implied, to the maximum extent permitted by applicable
20  * law, without malicious intent or gross negligence; in no event may
21  * licensor, an author or contributor be held liable for any indirect
22  * or other damage, or direct damage except proven a consequence of a
23  * direct error of said person and intended use of this work, loss or
24  * other issues arising in any way out of its use, even if advised of
25  * the possibility of such damage or existence of a nontrivial bug.
26  */
27 
28 #include <sys/param.h>
29 #include <sys/syscall.h>
30 #include <sys/signalvar.h>
31 #include <sys/mount.h>
32 #include <sys/fcntl.h>
33 #include <sys/exec.h>
34 #include <sys/exec_olf.h>
35 #include <sys/malloc.h>
36 #include <sys/stat.h>
37 #include <compat/common/compat_util.h>
38 #include <compat/common/kern_gen.h>
39 #include <compat/openbsd/compat_openbsd.h>
40 #include <compat/openbsd/openbsd_syscallargs.h>
41 
42 struct stat_compat {
43 	dev_t	  st_dev;
44 	ino_t	  st_ino;
45 	mode_t	  st_mode;
46 	nlink_t	  st_nlink;
47 	uid_t	  st_uid;
48 	gid_t	  st_gid;
49 	dev_t	  st_rdev;
50 	int32_t	  st_lspare0;
51 	struct	timespec_compat st_atimespec;
52 	struct	timespec_compat st_mtimespec;
53 	struct	timespec_compat st_ctimespec;
54 	off_t	  st_size;
55 	int64_t	  st_blocks;
56 	u_int32_t st_blksize;
57 	u_int32_t st_flags;
58 	u_int32_t st_gen;
59 	int32_t	  st_lspare1;
60 	struct	timespec_compat __st_birthtimespec;
61 	int64_t	  st_qspare[2];
62 };
63 
64 static void cvtstat(struct stat *, struct stat_compat *);
65 extern int sys_stat(struct proc *, void *, register_t *);
66 extern int sys_lstat(struct proc *, void *, register_t *);
67 extern int sys_fstat(struct proc *, void *, register_t *);
68 extern int sys_fhstat(struct proc *, void *, register_t *);
69 
70 
71 /*
72  * Convert from a new to an old stat structure.
73  */
74 static void
cvtstat(struct stat * st,struct stat_compat * ost)75 cvtstat(struct stat *st, struct stat_compat *ost)
76 {
77 	ost->st_dev = st->st_dev;
78 	ost->st_ino = st->st_ino;
79 	ost->st_mode = st->st_mode;
80 	ost->st_nlink = st->st_nlink;
81 	ost->st_uid = st->st_uid;
82 	ost->st_gid = st->st_gid;
83 	ost->st_rdev = st->st_rdev;
84 	ost->st_atimespec.tv_sec = __BOUNDLONG(st->st_atimespec.tv_sec);
85 	ost->st_atimespec.tv_nsec = st->st_atimespec.tv_nsec;
86 	ost->st_mtimespec.tv_sec = __BOUNDLONG(st->st_mtimespec.tv_sec);
87 	ost->st_mtimespec.tv_nsec = st->st_mtimespec.tv_nsec;
88 	ost->st_ctimespec.tv_sec = __BOUNDLONG(st->st_ctimespec.tv_sec);
89 	ost->st_ctimespec.tv_nsec = st->st_ctimespec.tv_nsec;
90 	ost->st_size = st->st_size;
91 	ost->st_blocks = st->st_blocks;
92 	ost->st_blksize = st->st_blksize;
93 	ost->st_flags = st->st_flags;
94 	ost->st_gen = st->st_gen;
95 	ost->st_lspare0 = st->st_lspare0;
96 	ost->st_lspare1 = st->st_lspare1;
97 	ost->st_qspare[0] = st->st_qspare[0];
98 	ost->st_qspare[1] = st->st_qspare[1];
99 	ost->__st_birthtimespec.tv_sec =
100 	    __BOUNDLONG(st->__st_birthtimespec.tv_sec);
101 	ost->__st_birthtimespec.tv_nsec = st->__st_birthtimespec.tv_nsec;
102 }
103 
104 int
compat_36_sys_stat(struct proc * p,void * v,register_t * retval)105 compat_36_sys_stat(struct proc *p, void *v, register_t *retval)
106 {
107 	struct compat_36_sys_stat_args /* {
108 		syscallarg(const char *) path;
109 		syscallarg(struct stat_compat *) ub;
110 	} */ *uap = v;
111 	struct sys_stat_args {
112 		syscallarg(const char *) path;
113 		syscallarg(struct stat *) ub;
114 	} bap;
115 	struct stat sb, *sbp = NULL;
116 	struct stat_compat osb;
117 	caddr_t sg = stackgap_init(p->p_emul);
118 	int error;
119 
120 	OPENBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
121 	SCARG(&bap, path) = SCARG(uap, path);
122 	if (SCARG(uap, ub) != NULL)
123 		sbp = stackgap_alloc(&sg, sizeof(sb));
124 	SCARG(&bap, ub) = sbp;
125 
126 	if ((error = sys_stat(p, &bap, retval)))
127 		return error;
128 
129 	if (SCARG(uap, ub) != NULL) {
130 		if ((error = copyin(sbp, (void *)&sb, sizeof(sb))))
131 			return error;
132 		cvtstat(&sb, &osb);
133 		if ((error = copyout(&osb, SCARG(uap, ub), sizeof(osb))))
134 			return error;
135 	}
136 
137 	return error;
138 }
139 
140 int
compat_36_sys_lstat(struct proc * p,void * v,register_t * retval)141 compat_36_sys_lstat(struct proc *p, void *v, register_t *retval)
142 {
143 	struct compat_36_sys_lstat_args /* {
144 		syscallarg(const char *) path;
145 		syscallarg(struct stat_compat *) ub;
146 	} */ *uap = v;
147 	struct sys_lstat_args {
148 		syscallarg(const char *) path;
149 		syscallarg(struct stat *) ub;
150 	} bap;
151 	struct stat sb, *sbp = NULL;
152 	struct stat_compat osb;
153 	caddr_t sg = stackgap_init(p->p_emul);
154 	int error;
155 
156 	OPENBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
157 	SCARG(&bap, path) = SCARG(uap, path);
158 	if (SCARG(uap, ub) != NULL)
159 		sbp = stackgap_alloc(&sg, sizeof(sb));
160 	SCARG(&bap, ub) = sbp;
161 
162 	if ((error = sys_lstat(p, &bap, retval)))
163 		return error;
164 
165 	if (SCARG(uap, ub) != NULL) {
166 		if ((error = copyin(sbp, (void *)&sb, sizeof(sb))))
167 			return error;
168 		cvtstat(&sb, &osb);
169 		if ((error = copyout(&osb, SCARG(uap, ub), sizeof(osb))))
170 			return error;
171 	}
172 
173 	return error;
174 }
175 
176 int
compat_36_sys_fstat(struct proc * p,void * v,register_t * retval)177 compat_36_sys_fstat(struct proc *p, void *v, register_t *retval)
178 {
179 	struct compat_36_sys_fstat_args /* {
180 		syscallarg(int) fd;
181 		syscallarg(struct stat_compat *) sb;
182 	} */ *uap = v;
183 	struct sys_fstat_args {
184 		syscallarg(int) fd;
185 		syscallarg(struct stat *) sb;
186 	} bap;
187 	struct stat sb, *sbp = NULL;
188 	struct stat_compat osb;
189 	caddr_t sg = stackgap_init(p->p_emul);
190 	int error;
191 
192 	SCARG(&bap, fd) = SCARG(uap, fd);
193 	if (SCARG(uap, sb) != NULL)
194 		sbp = stackgap_alloc(&sg, sizeof(sb));
195 	SCARG(&bap, sb) = sbp;
196 
197 	if ((error = sys_fstat(p, &bap, retval)))
198 		return error;
199 
200 	if (SCARG(uap, sb) != NULL) {
201 		if ((error = copyin(sbp, (void *)&sb, sizeof(sb))))
202 			return error;
203 		cvtstat(&sb, &osb);
204 		if ((error = copyout(&osb, SCARG(uap, sb), sizeof(osb))))
205 			return error;
206 	}
207 
208 	return error;
209 }
210 
211 int
compat_36_sys_fhstat(struct proc * p,void * v,register_t * retval)212 compat_36_sys_fhstat(struct proc *p, void *v, register_t *retval)
213 {
214 	struct compat_36_sys_fhstat_args /* {
215 		syscallarg(const fhandle_t *) fhp;
216 		syscallarg(struct stat *) sb;
217 	} */ *uap = v;
218 	struct sys_fstat_args {
219 		syscallarg(const fhandle_t *) fhp;
220 		syscallarg(struct stat *) sb;
221 	} bap;
222 	struct stat sb, *sbp = NULL;
223 	struct stat_compat osb;
224 	caddr_t sg = stackgap_init(p->p_emul);
225 	int error;
226 
227 	SCARG(&bap, fhp) = SCARG(uap, fhp);
228 	if (SCARG(uap, sb) != NULL)
229 		sbp = stackgap_alloc(&sg, sizeof(sb));
230 	SCARG(&bap, sb) = sbp;
231 
232 	if ((error = sys_fhstat(p, &bap, retval)))
233 		return error;
234 
235 	if (SCARG(uap, sb) != NULL) {
236 		if ((error = copyin(sbp, (void *)&sb, sizeof(sb))))
237 			return error;
238 		cvtstat(&sb, &osb);
239 		if ((error = copyout(&osb, SCARG(uap, sb), sizeof(osb))))
240 			return error;
241 	}
242 
243 	return error;
244 }
245