1 /** $MirOS: src/sys/compat/openbsd/openbsd_stat35.c,v 1.1.7.1 2005/03/06 16:33:43 tg Exp $ */
2 /* $OpenBSD: vfs_syscalls_35.c,v 1.3 2004/07/14 18:57:57 millert Exp $ */
3
4 /*
5 * Copyright (c) 1989, 1993
6 * The Regents of the University of California. All rights reserved.
7 * (c) UNIX System Laboratories, Inc.
8 * All or some portions of this file are derived from material licensed
9 * to the University of California by American Telephone and Telegraph
10 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
11 * the permission of UNIX System Laboratories, Inc.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 *
37 * @(#)vfs_syscalls.c 8.28 (Berkeley) 12/10/94
38 */
39
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/filedesc.h>
43 #include <sys/kernel.h>
44 #include <sys/proc.h>
45 #include <sys/file.h>
46 #include <sys/vnode.h>
47 #include <sys/namei.h>
48 #include <sys/dirent.h>
49 #include <sys/socket.h>
50 #include <sys/socketvar.h>
51 #include <sys/stat.h>
52
53 #include <sys/mount.h>
54 #include <compat/common/compat_util.h>
55 #include <compat/common/kern_gen.h>
56 #include <compat/openbsd/compat_openbsd.h>
57 #include <compat/openbsd/openbsd_syscallargs.h>
58
59 struct stat35 {
60 dev_t st_dev; /* inode's device */
61 ino_t st_ino; /* inode's number */
62 u_int16_t st_mode; /* inode protection mode */
63 u_int16_t st_nlink; /* number of hard links */
64 uid_t st_uid; /* user ID of the file's owner */
65 gid_t st_gid; /* group ID of the file's group */
66 dev_t st_rdev; /* device type */
67 struct timespec_compat st_atimespec; /* time of last access */
68 struct timespec_compat st_mtimespec; /* time of last data modification */
69 struct timespec_compat st_ctimespec; /* time of last file status change */
70 off_t st_size; /* file size, in bytes */
71 int64_t st_blocks; /* blocks allocated for file */
72 u_int32_t st_blksize; /* optimal blocksize for I/O */
73 u_int32_t st_flags; /* user defined flags for file */
74 u_int32_t st_gen; /* file generation number */
75 int32_t st_lspare;
76 int64_t st_qspare[2];
77 };
78
79 #if defined(COMPAT_OPENBSD)
80 static void cvtstat(struct stat *, struct stat35 *);
81
82 /*
83 * Convert from a new to an old stat structure.
84 */
85 static void
cvtstat(struct stat * st,struct stat35 * ost)86 cvtstat(struct stat *st, struct stat35 *ost)
87 {
88
89 ost->st_dev = st->st_dev;
90 ost->st_ino = st->st_ino;
91 ost->st_mode = st->st_mode & 0xffff;
92 ost->st_nlink = st->st_nlink & 0xffff;
93 ost->st_uid = st->st_uid;
94 ost->st_gid = st->st_gid;
95 ost->st_rdev = st->st_rdev;
96 ost->st_atimespec.tv_sec = __BOUNDLONG(st->st_atimespec.tv_sec);
97 ost->st_atimespec.tv_nsec = st->st_atimespec.tv_nsec;
98 ost->st_mtimespec.tv_sec = __BOUNDLONG(st->st_mtimespec.tv_sec);
99 ost->st_mtimespec.tv_nsec = st->st_mtimespec.tv_nsec;
100 ost->st_ctimespec.tv_sec = __BOUNDLONG(st->st_ctimespec.tv_sec);
101 ost->st_ctimespec.tv_nsec = st->st_ctimespec.tv_nsec;
102 ost->st_size = st->st_size;
103 ost->st_blocks = st->st_blocks;
104 ost->st_blksize = st->st_blksize;
105 ost->st_flags = st->st_flags;
106 ost->st_gen = st->st_gen;
107 }
108
109 /*
110 * Get file status; this version follows links.
111 */
112 /* ARGSUSED */
113 int
compat_35_sys_stat(struct proc * p,void * v,register_t * retval)114 compat_35_sys_stat(struct proc *p, void *v, register_t *retval)
115 {
116 struct compat_35_sys_stat_args /* {
117 syscallarg(char *) path;
118 syscallarg(struct stat35 *) ub;
119 } */ *uap = v;
120 struct stat sb;
121 struct stat35 osb;
122 int error;
123 struct nameidata nd;
124 caddr_t sg = stackgap_init(p->p_emul);
125
126 OPENBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
127 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
128 SCARG(uap, path), p);
129 if ((error = namei(&nd)) != 0)
130 return (error);
131 error = vn_stat(nd.ni_vp, &sb, p);
132 vput(nd.ni_vp);
133 if (error)
134 return (error);
135 /* Don't let non-root see generation numbers (for NFS security) */
136 if (suser(p, 0))
137 sb.st_gen = 0;
138 cvtstat(&sb, &osb);
139 error = copyout(&osb, SCARG(uap, ub), sizeof(osb));
140 return (error);
141 }
142
143 /*
144 * Get file status; this version does not follow links.
145 */
146 /* ARGSUSED */
147 int
compat_35_sys_lstat(struct proc * p,void * v,register_t * retval)148 compat_35_sys_lstat(struct proc *p, void *v, register_t *retval)
149 {
150 struct compat_35_sys_lstat_args /* {
151 syscallarg(char *) path;
152 syscallarg(struct stat35 *) ub;
153 } */ *uap = v;
154 struct stat sb;
155 struct stat35 osb;
156 int error;
157 struct nameidata nd;
158 caddr_t sg = stackgap_init(p->p_emul);
159
160 OPENBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
161 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE,
162 SCARG(uap, path), p);
163 if ((error = namei(&nd)) != 0)
164 return (error);
165 error = vn_stat(nd.ni_vp, &sb, p);
166 vput(nd.ni_vp);
167 if (error)
168 return (error);
169 /* Don't let non-root see generation numbers (for NFS security) */
170 if (suser(p, 0))
171 sb.st_gen = 0;
172 cvtstat(&sb, &osb);
173 error = copyout(&osb, SCARG(uap, ub), sizeof(osb));
174 return (error);
175 }
176
177 /*
178 * Return status information about a file descriptor.
179 */
180 /* ARGSUSED */
181 int
compat_35_sys_fstat(struct proc * p,void * v,register_t * retval)182 compat_35_sys_fstat(struct proc *p, void *v, register_t *retval)
183 {
184 struct compat_35_sys_fstat_args /* {
185 syscallarg(int) fd;
186 syscallarg(struct stat35 *) sb;
187 } */ *uap = v;
188 int fd = SCARG(uap, fd);
189 struct filedesc *fdp = p->p_fd;
190 struct file *fp;
191 struct stat ub;
192 struct stat35 oub;
193 int error;
194
195 if ((fp = fd_getfile(fdp, fd)) == NULL)
196 return (EBADF);
197 FREF(fp);
198 error = (*fp->f_ops->fo_stat)(fp, &ub, p);
199 FRELE(fp);
200 if (error == 0) {
201 /* Don't let non-root see generation numbers
202 (for NFS security) */
203 if (suser(p, 0))
204 ub.st_gen = 0;
205 cvtstat(&ub, &oub);
206 error = copyout(&oub, SCARG(uap, sb), sizeof(oub));
207 }
208 return (error);
209 }
210
211 /* ARGSUSED */
212 int
compat_35_sys_fhstat(struct proc * p,void * v,register_t * retval)213 compat_35_sys_fhstat(struct proc *p, void *v, register_t *retval)
214 {
215 struct compat_35_sys_fhstat_args /* {
216 syscallarg(const fhandle_t *) fhp;
217 syscallarg(struct stat35 *) sb;
218 } */ *uap = v;
219 struct stat ub;
220 struct stat35 oub;
221 int error;
222 fhandle_t fh;
223 struct mount *mp;
224 struct vnode *vp;
225
226 /*
227 * Must be super user
228 */
229 if ((error = suser(p, 0)))
230 return (error);
231
232 if ((error = copyin(SCARG(uap, fhp), &fh, sizeof(fhandle_t))) != 0)
233 return (error);
234
235 if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL)
236 return (ESTALE);
237 if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp)))
238 return (error);
239 error = vn_stat(vp, &ub, p);
240 vput(vp);
241 if (error)
242 return (error);
243 cvtstat(&ub, &oub);
244 error = copyout(&oub, SCARG(uap, sb), sizeof(oub));
245 return (error);
246 }
247 #endif /* def COMPAT_OPENBSD */
248