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