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