Sun Jan 29 07:16:01 2012 UTC ()
Rename static inline "helper" functions:
   ufsclass2qtype -> quota_idtype_to_ufs
   qtype2ufsclass -> quota_idtype_from_ufs

The reason for the direction of "ufs" changing is that the old names
were among the symbols using "ufs" to mean "fs-independent". So the
old names were for translating "ufsclass" (fs-independent quota id
type) to "qtype" (ufs-specific quota id type) and vice versa.

These functions are used in only two places, both of which are
inappropriate, so at some point they should probably be removed.
They're also identity transformations so not particularly helpful,
unless one were to make a careful and concerted effort to distinguish
the ufs quota code numbers from the fs-independent ones. This has not
been done and is probably impossible without support from a program
verifier, and maybe not even then.

They are static inline, so no compat concerns arise.

Also adjust the symbols they use to avoid <quota/quotaprop.h>.


(dholland)
diff -r1.12 -r1.13 src/sys/compat/common/vfs_syscalls_50.c
diff -r1.28 -r1.29 src/sys/ufs/ufs/quota.h
diff -r1.42 -r1.43 src/usr.sbin/edquota/edquota.c

cvs diff -r1.12 -r1.13 src/sys/compat/common/vfs_syscalls_50.c (switch to unified diff)

--- src/sys/compat/common/vfs_syscalls_50.c 2012/01/29 06:29:04 1.12
+++ src/sys/compat/common/vfs_syscalls_50.c 2012/01/29 07:16:00 1.13
@@ -1,544 +1,550 @@ @@ -1,544 +1,550 @@
1/* $NetBSD: vfs_syscalls_50.c,v 1.12 2012/01/29 06:29:04 dholland Exp $ */ 1/* $NetBSD: vfs_syscalls_50.c,v 1.13 2012/01/29 07:16:00 dholland Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Christos Zoulas. 8 * by Christos Zoulas.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software 18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement: 19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD 20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors. 21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its 22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived 23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission. 24 * from this software without specific prior written permission.
25 * 25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE. 36 * POSSIBILITY OF SUCH DAMAGE.
37 */ 37 */
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls_50.c,v 1.12 2012/01/29 06:29:04 dholland Exp $"); 39__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls_50.c,v 1.13 2012/01/29 07:16:00 dholland Exp $");
40 40
41#include <sys/param.h> 41#include <sys/param.h>
42#include <sys/systm.h> 42#include <sys/systm.h>
43#include <sys/namei.h> 43#include <sys/namei.h>
44#include <sys/filedesc.h> 44#include <sys/filedesc.h>
45#include <sys/kernel.h> 45#include <sys/kernel.h>
46#include <sys/file.h> 46#include <sys/file.h>
47#include <sys/stat.h> 47#include <sys/stat.h>
48#include <sys/socketvar.h> 48#include <sys/socketvar.h>
49#include <sys/vnode.h> 49#include <sys/vnode.h>
50#include <sys/mount.h> 50#include <sys/mount.h>
51#include <sys/proc.h> 51#include <sys/proc.h>
52#include <sys/uio.h> 52#include <sys/uio.h>
53#include <sys/dirent.h> 53#include <sys/dirent.h>
54#include <sys/malloc.h> 54#include <sys/malloc.h>
55#include <sys/kauth.h> 55#include <sys/kauth.h>
56#include <sys/time.h> 56#include <sys/time.h>
57#include <sys/vfs_syscalls.h> 57#include <sys/vfs_syscalls.h>
58#ifndef LFS 58#ifndef LFS
59#define LFS 59#define LFS
60#endif 60#endif
61#include <sys/syscallargs.h> 61#include <sys/syscallargs.h>
62 62
63#include <ufs/lfs/lfs_extern.h> 63#include <ufs/lfs/lfs_extern.h>
64 64
65#include <sys/quota.h> 65#include <sys/quota.h>
66#include <quota/quotaprop.h> 66#include <quota/quotaprop.h>
67#include <ufs/ufs/quota1.h> 67#include <ufs/ufs/quota1.h>
68 68
69#include <compat/common/compat_util.h> 69#include <compat/common/compat_util.h>
70#include <compat/sys/time.h> 70#include <compat/sys/time.h>
71#include <compat/sys/stat.h> 71#include <compat/sys/stat.h>
72#include <compat/sys/dirent.h> 72#include <compat/sys/dirent.h>
73#include <compat/sys/mount.h> 73#include <compat/sys/mount.h>
74 74
75static void cvtstat(struct stat30 *, const struct stat *); 75static void cvtstat(struct stat30 *, const struct stat *);
76 76
77/* 77/*
78 * Convert from a new to an old stat structure. 78 * Convert from a new to an old stat structure.
79 */ 79 */
80static void 80static void
81cvtstat(struct stat30 *ost, const struct stat *st) 81cvtstat(struct stat30 *ost, const struct stat *st)
82{ 82{
83 83
84 ost->st_dev = st->st_dev; 84 ost->st_dev = st->st_dev;
85 ost->st_ino = st->st_ino; 85 ost->st_ino = st->st_ino;
86 ost->st_mode = st->st_mode; 86 ost->st_mode = st->st_mode;
87 ost->st_nlink = st->st_nlink; 87 ost->st_nlink = st->st_nlink;
88 ost->st_uid = st->st_uid; 88 ost->st_uid = st->st_uid;
89 ost->st_gid = st->st_gid; 89 ost->st_gid = st->st_gid;
90 ost->st_rdev = st->st_rdev; 90 ost->st_rdev = st->st_rdev;
91 timespec_to_timespec50(&st->st_atimespec, &ost->st_atimespec); 91 timespec_to_timespec50(&st->st_atimespec, &ost->st_atimespec);
92 timespec_to_timespec50(&st->st_mtimespec, &ost->st_mtimespec); 92 timespec_to_timespec50(&st->st_mtimespec, &ost->st_mtimespec);
93 timespec_to_timespec50(&st->st_ctimespec, &ost->st_ctimespec); 93 timespec_to_timespec50(&st->st_ctimespec, &ost->st_ctimespec);
94 timespec_to_timespec50(&st->st_birthtimespec, &ost->st_birthtimespec); 94 timespec_to_timespec50(&st->st_birthtimespec, &ost->st_birthtimespec);
95 ost->st_size = st->st_size; 95 ost->st_size = st->st_size;
96 ost->st_blocks = st->st_blocks; 96 ost->st_blocks = st->st_blocks;
97 ost->st_blksize = st->st_blksize; 97 ost->st_blksize = st->st_blksize;
98 ost->st_flags = st->st_flags; 98 ost->st_flags = st->st_flags;
99 ost->st_gen = st->st_gen; 99 ost->st_gen = st->st_gen;
100 memset(ost->st_spare, 0, sizeof(ost->st_spare)); 100 memset(ost->st_spare, 0, sizeof(ost->st_spare));
101} 101}
102 102
103/* 103/*
104 * Get file status; this version follows links. 104 * Get file status; this version follows links.
105 */ 105 */
106/* ARGSUSED */ 106/* ARGSUSED */
107int 107int
108compat_50_sys___stat30(struct lwp *l, const struct compat_50_sys___stat30_args *uap, register_t *retval) 108compat_50_sys___stat30(struct lwp *l, const struct compat_50_sys___stat30_args *uap, register_t *retval)
109{ 109{
110 /* { 110 /* {
111 syscallarg(const char *) path; 111 syscallarg(const char *) path;
112 syscallarg(struct stat30 *) ub; 112 syscallarg(struct stat30 *) ub;
113 } */ 113 } */
114 struct stat sb; 114 struct stat sb;
115 struct stat30 osb; 115 struct stat30 osb;
116 int error; 116 int error;
117 117
118 error = do_sys_stat(SCARG(uap, path), FOLLOW, &sb); 118 error = do_sys_stat(SCARG(uap, path), FOLLOW, &sb);
119 if (error) 119 if (error)
120 return error; 120 return error;
121 cvtstat(&osb, &sb); 121 cvtstat(&osb, &sb);
122 error = copyout(&osb, SCARG(uap, ub), sizeof (osb)); 122 error = copyout(&osb, SCARG(uap, ub), sizeof (osb));
123 return error; 123 return error;
124} 124}
125 125
126 126
127/* 127/*
128 * Get file status; this version does not follow links. 128 * Get file status; this version does not follow links.
129 */ 129 */
130/* ARGSUSED */ 130/* ARGSUSED */
131int 131int
132compat_50_sys___lstat30(struct lwp *l, const struct compat_50_sys___lstat30_args *uap, register_t *retval) 132compat_50_sys___lstat30(struct lwp *l, const struct compat_50_sys___lstat30_args *uap, register_t *retval)
133{ 133{
134 /* { 134 /* {
135 syscallarg(const char *) path; 135 syscallarg(const char *) path;
136 syscallarg(struct stat30 *) ub; 136 syscallarg(struct stat30 *) ub;
137 } */ 137 } */
138 struct stat sb; 138 struct stat sb;
139 struct stat30 osb; 139 struct stat30 osb;
140 int error; 140 int error;
141 141
142 error = do_sys_stat(SCARG(uap, path), NOFOLLOW, &sb); 142 error = do_sys_stat(SCARG(uap, path), NOFOLLOW, &sb);
143 if (error) 143 if (error)
144 return error; 144 return error;
145 cvtstat(&osb, &sb); 145 cvtstat(&osb, &sb);
146 error = copyout(&osb, SCARG(uap, ub), sizeof (osb)); 146 error = copyout(&osb, SCARG(uap, ub), sizeof (osb));
147 return error; 147 return error;
148} 148}
149 149
150/* 150/*
151 * Return status information about a file descriptor. 151 * Return status information about a file descriptor.
152 */ 152 */
153/* ARGSUSED */ 153/* ARGSUSED */
154int 154int
155compat_50_sys___fstat30(struct lwp *l, const struct compat_50_sys___fstat30_args *uap, register_t *retval) 155compat_50_sys___fstat30(struct lwp *l, const struct compat_50_sys___fstat30_args *uap, register_t *retval)
156{ 156{
157 /* { 157 /* {
158 syscallarg(int) fd; 158 syscallarg(int) fd;
159 syscallarg(struct stat30 *) sb; 159 syscallarg(struct stat30 *) sb;
160 } */ 160 } */
161 struct stat sb; 161 struct stat sb;
162 struct stat30 osb; 162 struct stat30 osb;
163 int error; 163 int error;
164 164
165 error = do_sys_fstat(SCARG(uap, fd), &sb); 165 error = do_sys_fstat(SCARG(uap, fd), &sb);
166 if (error) 166 if (error)
167 return error; 167 return error;
168 cvtstat(&osb, &sb); 168 cvtstat(&osb, &sb);
169 error = copyout(&osb, SCARG(uap, sb), sizeof (osb)); 169 error = copyout(&osb, SCARG(uap, sb), sizeof (osb));
170 return error; 170 return error;
171} 171}
172 172
173/* ARGSUSED */ 173/* ARGSUSED */
174int 174int
175compat_50_sys___fhstat40(struct lwp *l, const struct compat_50_sys___fhstat40_args *uap, register_t *retval) 175compat_50_sys___fhstat40(struct lwp *l, const struct compat_50_sys___fhstat40_args *uap, register_t *retval)
176{ 176{
177 /* { 177 /* {
178 syscallarg(const void *) fhp; 178 syscallarg(const void *) fhp;
179 syscallarg(size_t) fh_size; 179 syscallarg(size_t) fh_size;
180 syscallarg(struct stat30 *) sb; 180 syscallarg(struct stat30 *) sb;
181 } */ 181 } */
182 struct stat sb; 182 struct stat sb;
183 struct stat30 osb; 183 struct stat30 osb;
184 int error; 184 int error;
185 185
186 error = do_fhstat(l, SCARG(uap, fhp), SCARG(uap, fh_size), &sb); 186 error = do_fhstat(l, SCARG(uap, fhp), SCARG(uap, fh_size), &sb);
187 if (error) 187 if (error)
188 return error; 188 return error;
189 cvtstat(&osb, &sb); 189 cvtstat(&osb, &sb);
190 error = copyout(&osb, SCARG(uap, sb), sizeof (osb)); 190 error = copyout(&osb, SCARG(uap, sb), sizeof (osb));
191 return error; 191 return error;
192} 192}
193 193
194static int 194static int
195compat_50_do_sys_utimes(struct lwp *l, struct vnode *vp, const char *path, 195compat_50_do_sys_utimes(struct lwp *l, struct vnode *vp, const char *path,
196 int flag, const struct timeval50 *tptr) 196 int flag, const struct timeval50 *tptr)
197{ 197{
198 struct timeval tv[2], *tvp; 198 struct timeval tv[2], *tvp;
199 struct timeval50 tv50[2]; 199 struct timeval50 tv50[2];
200 if (tptr) { 200 if (tptr) {
201 int error = copyin(tptr, tv50, sizeof(tv50)); 201 int error = copyin(tptr, tv50, sizeof(tv50));
202 if (error) 202 if (error)
203 return error; 203 return error;
204 timeval50_to_timeval(&tv50[0], &tv[0]); 204 timeval50_to_timeval(&tv50[0], &tv[0]);
205 timeval50_to_timeval(&tv50[1], &tv[1]); 205 timeval50_to_timeval(&tv50[1], &tv[1]);
206 tvp = tv; 206 tvp = tv;
207 } else 207 } else
208 tvp = NULL; 208 tvp = NULL;
209 return do_sys_utimes(l, vp, path, flag, tvp, UIO_SYSSPACE); 209 return do_sys_utimes(l, vp, path, flag, tvp, UIO_SYSSPACE);
210} 210}
211  211
212/* 212/*
213 * Set the access and modification times given a path name; this 213 * Set the access and modification times given a path name; this
214 * version follows links. 214 * version follows links.
215 */ 215 */
216/* ARGSUSED */ 216/* ARGSUSED */
217int 217int
218compat_50_sys_utimes(struct lwp *l, const struct compat_50_sys_utimes_args *uap, 218compat_50_sys_utimes(struct lwp *l, const struct compat_50_sys_utimes_args *uap,
219 register_t *retval) 219 register_t *retval)
220{ 220{
221 /* { 221 /* {
222 syscallarg(const char *) path; 222 syscallarg(const char *) path;
223 syscallarg(const struct timeval50 *) tptr; 223 syscallarg(const struct timeval50 *) tptr;
224 } */ 224 } */
225 225
226 return compat_50_do_sys_utimes(l, NULL, SCARG(uap, path), FOLLOW, 226 return compat_50_do_sys_utimes(l, NULL, SCARG(uap, path), FOLLOW,
227 SCARG(uap, tptr)); 227 SCARG(uap, tptr));
228} 228}
229 229
230/* 230/*
231 * Set the access and modification times given a file descriptor. 231 * Set the access and modification times given a file descriptor.
232 */ 232 */
233/* ARGSUSED */ 233/* ARGSUSED */
234int 234int
235compat_50_sys_futimes(struct lwp *l, 235compat_50_sys_futimes(struct lwp *l,
236 const struct compat_50_sys_futimes_args *uap, register_t *retval) 236 const struct compat_50_sys_futimes_args *uap, register_t *retval)
237{ 237{
238 /* { 238 /* {
239 syscallarg(int) fd; 239 syscallarg(int) fd;
240 syscallarg(const struct timeval50 *) tptr; 240 syscallarg(const struct timeval50 *) tptr;
241 } */ 241 } */
242 int error; 242 int error;
243 struct file *fp; 243 struct file *fp;
244 244
245 /* fd_getvnode() will use the descriptor for us */ 245 /* fd_getvnode() will use the descriptor for us */
246 if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0) 246 if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
247 return error; 247 return error;
248 error = compat_50_do_sys_utimes(l, fp->f_data, NULL, 0, 248 error = compat_50_do_sys_utimes(l, fp->f_data, NULL, 0,
249 SCARG(uap, tptr)); 249 SCARG(uap, tptr));
250 fd_putfile(SCARG(uap, fd)); 250 fd_putfile(SCARG(uap, fd));
251 return error; 251 return error;
252} 252}
253 253
254/* 254/*
255 * Set the access and modification times given a path name; this 255 * Set the access and modification times given a path name; this
256 * version does not follow links. 256 * version does not follow links.
257 */ 257 */
258int 258int
259compat_50_sys_lutimes(struct lwp *l, 259compat_50_sys_lutimes(struct lwp *l,
260 const struct compat_50_sys_lutimes_args *uap, register_t *retval) 260 const struct compat_50_sys_lutimes_args *uap, register_t *retval)
261{ 261{
262 /* { 262 /* {
263 syscallarg(const char *) path; 263 syscallarg(const char *) path;
264 syscallarg(const struct timeval50 *) tptr; 264 syscallarg(const struct timeval50 *) tptr;
265 } */ 265 } */
266 266
267 return compat_50_do_sys_utimes(l, NULL, SCARG(uap, path), NOFOLLOW, 267 return compat_50_do_sys_utimes(l, NULL, SCARG(uap, path), NOFOLLOW,
268 SCARG(uap, tptr)); 268 SCARG(uap, tptr));
269} 269}
270 270
271int 271int
272compat_50_sys_lfs_segwait(struct lwp *l, 272compat_50_sys_lfs_segwait(struct lwp *l,
273 const struct compat_50_sys_lfs_segwait_args *uap, register_t *retval) 273 const struct compat_50_sys_lfs_segwait_args *uap, register_t *retval)
274{ 274{
275 /* { 275 /* {
276 syscallarg(fsid_t *) fsidp; 276 syscallarg(fsid_t *) fsidp;
277 syscallarg(struct timeval50 *) tv; 277 syscallarg(struct timeval50 *) tv;
278 } */ 278 } */
279#ifdef notyet 279#ifdef notyet
280 struct timeval atv; 280 struct timeval atv;
281 struct timeval50 atv50; 281 struct timeval50 atv50;
282 fsid_t fsid; 282 fsid_t fsid;
283 int error; 283 int error;
284 284
285 /* XXX need we be su to segwait? */ 285 /* XXX need we be su to segwait? */
286 if ((error = kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER, 286 if ((error = kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER,
287 NULL)) != 0) 287 NULL)) != 0)
288 return (error); 288 return (error);
289 if ((error = copyin(SCARG(uap, fsidp), &fsid, sizeof(fsid_t))) != 0) 289 if ((error = copyin(SCARG(uap, fsidp), &fsid, sizeof(fsid_t))) != 0)
290 return (error); 290 return (error);
291 291
292 if (SCARG(uap, tv)) { 292 if (SCARG(uap, tv)) {
293 error = copyin(SCARG(uap, tv), &atv50, sizeof(atv50)); 293 error = copyin(SCARG(uap, tv), &atv50, sizeof(atv50));
294 if (error) 294 if (error)
295 return (error); 295 return (error);
296 timeval50_to_timeval(&atv50, &atv); 296 timeval50_to_timeval(&atv50, &atv);
297 if (itimerfix(&atv)) 297 if (itimerfix(&atv))
298 return (EINVAL); 298 return (EINVAL);
299 } else /* NULL or invalid */ 299 } else /* NULL or invalid */
300 atv.tv_sec = atv.tv_usec = 0; 300 atv.tv_sec = atv.tv_usec = 0;
301 return lfs_segwait(&fsid, &atv); 301 return lfs_segwait(&fsid, &atv);
302#else 302#else
303 return ENOSYS; 303 return ENOSYS;
304#endif 304#endif
305} 305}
306 306
307int 307int
308compat_50_sys_mknod(struct lwp *l, 308compat_50_sys_mknod(struct lwp *l,
309 const struct compat_50_sys_mknod_args *uap, register_t *retval) 309 const struct compat_50_sys_mknod_args *uap, register_t *retval)
310{ 310{
311 /* { 311 /* {
312 syscallarg(const char *) path; 312 syscallarg(const char *) path;
313 syscallarg(mode_t) mode; 313 syscallarg(mode_t) mode;
314 syscallarg(uint32_t) dev; 314 syscallarg(uint32_t) dev;
315 } */ 315 } */
316 return do_sys_mknod(l, SCARG(uap, path), SCARG(uap, mode), 316 return do_sys_mknod(l, SCARG(uap, path), SCARG(uap, mode),
317 SCARG(uap, dev), retval, UIO_USERSPACE); 317 SCARG(uap, dev), retval, UIO_USERSPACE);
318} 318}
319 319
320/* ARGSUSED */ 320/* ARGSUSED */
321int  321int
322compat_50_sys_quotactl(struct lwp *l, const struct compat_50_sys_quotactl_args *uap, register_t *retval) 322compat_50_sys_quotactl(struct lwp *l, const struct compat_50_sys_quotactl_args *uap, register_t *retval)
323{ 323{
324 /* { 324 /* {
325 syscallarg(const char *) path; 325 syscallarg(const char *) path;
326 syscallarg(int) cmd; 326 syscallarg(int) cmd;
327 syscallarg(int) uid; 327 syscallarg(int) uid;
328 syscallarg(void *) arg;  328 syscallarg(void *) arg;
329 } */ 329 } */
330 struct mount *mp; 330 struct mount *mp;
331 int error; 331 int error;
332 uint8_t error8; 332 uint8_t error8;
333 struct vnode *vp; 333 struct vnode *vp;
334 int q1cmd = SCARG(uap, cmd); 334 int q1cmd = SCARG(uap, cmd);
335 prop_dictionary_t dict, data, cmd; 335 prop_dictionary_t dict, data, cmd;
336 prop_array_t cmds, datas; 336 prop_array_t cmds, datas;
337 char *bufpath; 337 char *bufpath;
338 struct dqblk dqblk; 338 struct dqblk dqblk;
339 struct quotaval qv[QUOTA_NLIMITS]; 339 struct quotaval qv[QUOTA_NLIMITS];
340 uint64_t *values[QUOTA_NLIMITS]; 340 uint64_t *values[QUOTA_NLIMITS];
 341 int idtype;
341 342
342 values[QUOTA_LIMIT_BLOCK] = &qv[QUOTA_LIMIT_BLOCK].qv_hardlimit; 343 values[QUOTA_LIMIT_BLOCK] = &qv[QUOTA_LIMIT_BLOCK].qv_hardlimit;
343 values[QUOTA_LIMIT_FILE] = &qv[QUOTA_LIMIT_FILE].qv_hardlimit; 344 values[QUOTA_LIMIT_FILE] = &qv[QUOTA_LIMIT_FILE].qv_hardlimit;
344 345
345 error = namei_simple_user(SCARG(uap, path), 346 error = namei_simple_user(SCARG(uap, path),
346 NSM_FOLLOW_TRYEMULROOT, &vp); 347 NSM_FOLLOW_TRYEMULROOT, &vp);
347 if (error != 0) 348 if (error != 0)
348 return (error);  349 return (error);
349 error = ENOMEM; 350 error = ENOMEM;
350 mp = vp->v_mount; 351 mp = vp->v_mount;
351 if ((dict = quota_prop_create()) == NULL) 352 if ((dict = quota_prop_create()) == NULL)
352 goto out; 353 goto out;
353 if ((cmds = prop_array_create()) == NULL) 354 if ((cmds = prop_array_create()) == NULL)
354 goto out_dict; 355 goto out_dict;
355 if ((datas = prop_array_create()) == NULL) 356 if ((datas = prop_array_create()) == NULL)
356 goto out_cmds; 357 goto out_cmds;
357 358
358 switch((q1cmd & ~SUBCMDMASK) >> SUBCMDSHIFT) { 359 switch((q1cmd & ~SUBCMDMASK) >> SUBCMDSHIFT) {
359 case Q_QUOTAON: 360 case Q_QUOTAON:
360 data = prop_dictionary_create(); 361 data = prop_dictionary_create();
361 if (data == NULL) 362 if (data == NULL)
362 goto out_datas; 363 goto out_datas;
363 bufpath = malloc(PATH_MAX * sizeof(char), M_TEMP, M_WAITOK); 364 bufpath = malloc(PATH_MAX * sizeof(char), M_TEMP, M_WAITOK);
364 if (bufpath == NULL) 365 if (bufpath == NULL)
365 goto out_data; 366 goto out_data;
366 error = copyinstr(SCARG(uap, arg), bufpath, PATH_MAX, NULL); 367 error = copyinstr(SCARG(uap, arg), bufpath, PATH_MAX, NULL);
367 if (error != 0) { 368 if (error != 0) {
368 free(bufpath, M_TEMP); 369 free(bufpath, M_TEMP);
369 goto out_data; 370 goto out_data;
370 } 371 }
371 if (!prop_dictionary_set_cstring(data, "quotafile", bufpath)) 372 if (!prop_dictionary_set_cstring(data, "quotafile", bufpath))
372 error = ENOMEM; 373 error = ENOMEM;
373 free(bufpath, M_TEMP); 374 free(bufpath, M_TEMP);
374 if (error) 375 if (error)
375 goto out_data; 376 goto out_data;
376 error = ENOMEM; 377 error = ENOMEM;
377 if (!prop_array_add_and_rel(datas, data)) 378 if (!prop_array_add_and_rel(datas, data))
378 goto out_datas; 379 goto out_datas;
 380 idtype = quota_idtype_from_ufs(q1cmd & SUBCMDMASK);
379 if (!quota_prop_add_command(cmds, "quotaon", 381 if (!quota_prop_add_command(cmds, "quotaon",
380 ufs_quota_class_names[qtype2ufsclass(q1cmd & SUBCMDMASK)], 382 ufs_quota_class_names[idtype],
381 datas)) 383 datas))
382 goto out_cmds; 384 goto out_cmds;
383 goto do_quotaonoff; 385 goto do_quotaonoff;
384 386
385 case Q_QUOTAOFF: 387 case Q_QUOTAOFF:
386 error = ENOMEM; 388 error = ENOMEM;
 389 idtype = quota_idtype_from_ufs(q1cmd & SUBCMDMASK);
387 if (!quota_prop_add_command(cmds, "quotaoff", 390 if (!quota_prop_add_command(cmds, "quotaoff",
388 ufs_quota_class_names[qtype2ufsclass(q1cmd & SUBCMDMASK)], 391 ufs_quota_class_names[idtype],
389 datas)) 392 datas))
390 goto out_cmds; 393 goto out_cmds;
391do_quotaonoff: 394do_quotaonoff:
392 if (!prop_dictionary_set_and_rel(dict, "commands", cmds)) 395 if (!prop_dictionary_set_and_rel(dict, "commands", cmds))
393 goto out_dict; 396 goto out_dict;
394 error = vfs_quotactl(mp, dict); 397 error = vfs_quotactl(mp, dict);
395 if (error) 398 if (error)
396 goto out_dict; 399 goto out_dict;
397 if ((error = quota_get_cmds(dict, &cmds)) != 0) 400 if ((error = quota_get_cmds(dict, &cmds)) != 0)
398 goto out_dict; 401 goto out_dict;
399 cmd = prop_array_get(cmds, 0); 402 cmd = prop_array_get(cmds, 0);
400 if (cmd == NULL) { 403 if (cmd == NULL) {
401 error = EINVAL; 404 error = EINVAL;
402 goto out_dict; 405 goto out_dict;
403 } 406 }
404 if (!prop_dictionary_get_int8(cmd, "return", &error8)) { 407 if (!prop_dictionary_get_int8(cmd, "return", &error8)) {
405 error = EINVAL; 408 error = EINVAL;
406 goto out_dict; 409 goto out_dict;
407 } 410 }
408 error = error8; 411 error = error8;
409 goto out_dict; 412 goto out_dict;
410 413
411 case Q_GETQUOTA: 414 case Q_GETQUOTA:
412 error = ENOMEM; 415 error = ENOMEM;
413 data = prop_dictionary_create(); 416 data = prop_dictionary_create();
414 if (data == NULL) 417 if (data == NULL)
415 goto out_datas; 418 goto out_datas;
416 if (!prop_dictionary_set_uint32(data, "id", SCARG(uap, uid))) 419 if (!prop_dictionary_set_uint32(data, "id", SCARG(uap, uid)))
417 goto out_data; 420 goto out_data;
418 if (!prop_array_add_and_rel(datas, data)) 421 if (!prop_array_add_and_rel(datas, data))
419 goto out_datas; 422 goto out_datas;
 423 idtype = quota_idtype_from_ufs(q1cmd & SUBCMDMASK);
420 if (!quota_prop_add_command(cmds, "get", 424 if (!quota_prop_add_command(cmds, "get",
421 ufs_quota_class_names[qtype2ufsclass(q1cmd & SUBCMDMASK)], 425 ufs_quota_class_names[idtype],
422 datas)) 426 datas))
423 goto out_cmds; 427 goto out_cmds;
424 if (!prop_dictionary_set_and_rel(dict, "commands", cmds)) 428 if (!prop_dictionary_set_and_rel(dict, "commands", cmds))
425 goto out_dict; 429 goto out_dict;
426 error = vfs_quotactl(mp, dict); 430 error = vfs_quotactl(mp, dict);
427 if (error) 431 if (error)
428 goto out_dict; 432 goto out_dict;
429 if ((error = quota_get_cmds(dict, &cmds)) != 0) 433 if ((error = quota_get_cmds(dict, &cmds)) != 0)
430 goto out_dict; 434 goto out_dict;
431 cmd = prop_array_get(cmds, 0); 435 cmd = prop_array_get(cmds, 0);
432 if (cmd == NULL) { 436 if (cmd == NULL) {
433 error = EINVAL; 437 error = EINVAL;
434 goto out_dict; 438 goto out_dict;
435 } 439 }
436 if (!prop_dictionary_get_int8(cmd, "return", &error8)) { 440 if (!prop_dictionary_get_int8(cmd, "return", &error8)) {
437 error = EINVAL; 441 error = EINVAL;
438 goto out_dict; 442 goto out_dict;
439 } 443 }
440 error = error8; 444 error = error8;
441 if (error) 445 if (error)
442 goto out_dict; 446 goto out_dict;
443 datas = prop_dictionary_get(cmd, "data"); 447 datas = prop_dictionary_get(cmd, "data");
444 error = EINVAL; 448 error = EINVAL;
445 if (datas == NULL) 449 if (datas == NULL)
446 goto out_dict; 450 goto out_dict;
447 data = prop_array_get(datas, 0); 451 data = prop_array_get(datas, 0);
448 if (data == NULL) 452 if (data == NULL)
449 goto out_dict; 453 goto out_dict;
450 error = proptoquota64(data, values, 454 error = proptoquota64(data, values,
451 ufs_quota_entry_names, UFS_QUOTA_NENTRIES, 455 ufs_quota_entry_names, UFS_QUOTA_NENTRIES,
452 ufs_quota_limit_names, QUOTA_NLIMITS); 456 ufs_quota_limit_names, QUOTA_NLIMITS);
453 if (error) 457 if (error)
454 goto out_dict; 458 goto out_dict;
455 quotavals_to_dqblk(&qv[QUOTA_LIMIT_BLOCK], 459 quotavals_to_dqblk(&qv[QUOTA_LIMIT_BLOCK],
456 &qv[QUOTA_LIMIT_FILE], 460 &qv[QUOTA_LIMIT_FILE],
457 &dqblk); 461 &dqblk);
458 error = copyout(&dqblk, SCARG(uap, arg), sizeof(dqblk)); 462 error = copyout(&dqblk, SCARG(uap, arg), sizeof(dqblk));
459 goto out_dict; 463 goto out_dict;
460  464
461 case Q_SETQUOTA: 465 case Q_SETQUOTA:
462 error = copyin(SCARG(uap, arg), &dqblk, sizeof(dqblk)); 466 error = copyin(SCARG(uap, arg), &dqblk, sizeof(dqblk));
463 if (error) 467 if (error)
464 goto out_datas; 468 goto out_datas;
465 dqblk_to_quotavals(&dqblk, &qv[QUOTA_LIMIT_BLOCK], 469 dqblk_to_quotavals(&dqblk, &qv[QUOTA_LIMIT_BLOCK],
466 &qv[QUOTA_LIMIT_FILE]); 470 &qv[QUOTA_LIMIT_FILE]);
467 471
468 error = ENOMEM; 472 error = ENOMEM;
469 data = quota64toprop(SCARG(uap, uid), 0, values, 473 data = quota64toprop(SCARG(uap, uid), 0, values,
470 ufs_quota_entry_names, UFS_QUOTA_NENTRIES, 474 ufs_quota_entry_names, UFS_QUOTA_NENTRIES,
471 ufs_quota_limit_names, QUOTA_NLIMITS); 475 ufs_quota_limit_names, QUOTA_NLIMITS);
472 if (data == NULL) 476 if (data == NULL)
473 goto out_data; 477 goto out_data;
474 if (!prop_array_add_and_rel(datas, data)) 478 if (!prop_array_add_and_rel(datas, data))
475 goto out_datas; 479 goto out_datas;
 480 idtype = quota_idtype_from_ufs(q1cmd & SUBCMDMASK);
476 if (!quota_prop_add_command(cmds, "set", 481 if (!quota_prop_add_command(cmds, "set",
477 ufs_quota_class_names[qtype2ufsclass(q1cmd & SUBCMDMASK)], 482 ufs_quota_class_names[idtype],
478 datas)) 483 datas))
479 goto out_cmds; 484 goto out_cmds;
480 if (!prop_dictionary_set_and_rel(dict, "commands", cmds)) 485 if (!prop_dictionary_set_and_rel(dict, "commands", cmds))
481 goto out_dict; 486 goto out_dict;
482 error = vfs_quotactl(mp, dict); 487 error = vfs_quotactl(mp, dict);
483 if (error) 488 if (error)
484 goto out_dict; 489 goto out_dict;
485 if ((error = quota_get_cmds(dict, &cmds)) != 0) 490 if ((error = quota_get_cmds(dict, &cmds)) != 0)
486 goto out_dict; 491 goto out_dict;
487 cmd = prop_array_get(cmds, 0); 492 cmd = prop_array_get(cmds, 0);
488 if (cmd == NULL) { 493 if (cmd == NULL) {
489 error = EINVAL; 494 error = EINVAL;
490 goto out_dict; 495 goto out_dict;
491 } 496 }
492 if (!prop_dictionary_get_int8(cmd, "return", &error8)) { 497 if (!prop_dictionary_get_int8(cmd, "return", &error8)) {
493 error = EINVAL; 498 error = EINVAL;
494 goto out_dict; 499 goto out_dict;
495 } 500 }
496 error = error8; 501 error = error8;
497 goto out_dict; 502 goto out_dict;
498  503
499 case Q_SYNC: 504 case Q_SYNC:
500 /* 505 /*
501 * not supported but used only to see if quota is supported, 506 * not supported but used only to see if quota is supported,
502 * emulate with a "get version" 507 * emulate with a "get version"
503 */ 508 */
504 error = ENOMEM; 509 error = ENOMEM;
 510 idtype = quota_idtype_from_ufs(q1cmd & SUBCMDMASK);
505 if (!quota_prop_add_command(cmds, "get version", 511 if (!quota_prop_add_command(cmds, "get version",
506 ufs_quota_class_names[qtype2ufsclass(q1cmd & SUBCMDMASK)], 512 ufs_quota_class_names[idtype],
507 datas)) 513 datas))
508 goto out_cmds; 514 goto out_cmds;
509 if (!prop_dictionary_set_and_rel(dict, "commands", cmds)) 515 if (!prop_dictionary_set_and_rel(dict, "commands", cmds))
510 goto out_dict; 516 goto out_dict;
511 error = vfs_quotactl(mp, dict); 517 error = vfs_quotactl(mp, dict);
512 if (error) 518 if (error)
513 goto out_dict; 519 goto out_dict;
514 if ((error = quota_get_cmds(dict, &cmds)) != 0) 520 if ((error = quota_get_cmds(dict, &cmds)) != 0)
515 goto out_dict; 521 goto out_dict;
516 cmd = prop_array_get(cmds, 0); 522 cmd = prop_array_get(cmds, 0);
517 if (cmd == NULL) { 523 if (cmd == NULL) {
518 error = EINVAL; 524 error = EINVAL;
519 goto out_dict; 525 goto out_dict;
520 } 526 }
521 if (!prop_dictionary_get_int8(cmd, "return", &error8)) { 527 if (!prop_dictionary_get_int8(cmd, "return", &error8)) {
522 error = EINVAL; 528 error = EINVAL;
523 goto out_dict; 529 goto out_dict;
524 } 530 }
525 error = error8; 531 error = error8;
526 goto out_dict; 532 goto out_dict;
527 533
528 case Q_SETUSE: 534 case Q_SETUSE:
529 default: 535 default:
530 error = EOPNOTSUPP; 536 error = EOPNOTSUPP;
531 goto out_datas; 537 goto out_datas;
532 } 538 }
533out_data: 539out_data:
534 prop_object_release(data); 540 prop_object_release(data);
535out_datas: 541out_datas:
536 prop_object_release(datas); 542 prop_object_release(datas);
537out_cmds: 543out_cmds:
538 prop_object_release(cmds); 544 prop_object_release(cmds);
539out_dict: 545out_dict:
540 prop_object_release(dict); 546 prop_object_release(dict);
541out: 547out:
542 vrele(vp); 548 vrele(vp);
543 return error; 549 return error;
544} 550}

cvs diff -r1.28 -r1.29 src/sys/ufs/ufs/quota.h (switch to unified diff)

--- src/sys/ufs/ufs/quota.h 2011/03/25 10:25:17 1.28
+++ src/sys/ufs/ufs/quota.h 2012/01/29 07:16:00 1.29
@@ -1,97 +1,97 @@ @@ -1,97 +1,97 @@
1/* $NetBSD: quota.h,v 1.28 2011/03/25 10:25:17 bouyer Exp $ */ 1/* $NetBSD: quota.h,v 1.29 2012/01/29 07:16:00 dholland Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1982, 1986, 1993 4 * Copyright (c) 1982, 1986, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Robert Elz at The University of Melbourne. 8 * Robert Elz at The University of Melbourne.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors 18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software 19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission. 20 * without specific prior written permission.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE. 32 * SUCH DAMAGE.
33 * 33 *
34 * @(#)quota.h 8.3 (Berkeley) 8/19/94 34 * @(#)quota.h 8.3 (Berkeley) 8/19/94
35 */ 35 */
36 36
37#ifndef _UFS_UFS_QUOTA_H_ 37#ifndef _UFS_UFS_QUOTA_H_
38#define _UFS_UFS_QUOTA_H_ 38#define _UFS_UFS_QUOTA_H_
39 39
40/* 40/*
41 * These definitions are common to the original disk quota implementation 41 * These definitions are common to the original disk quota implementation
42 * (quota1) and the newer implementation (quota2) 42 * (quota1) and the newer implementation (quota2)
43 */ 43 */
44 44
45/* 45/*
46 * The following constants define the usage of the quota file array in the 46 * The following constants define the usage of the quota file array in the
47 * ufsmount structure and dquot array in the inode structure. The semantics 47 * ufsmount structure and dquot array in the inode structure. The semantics
48 * of the elements of these arrays are defined in the routine getinoquota; 48 * of the elements of these arrays are defined in the routine getinoquota;
49 * the remainder of the quota code treats them generically and need not be 49 * the remainder of the quota code treats them generically and need not be
50 * inspected when changing the size of the array. 50 * inspected when changing the size of the array.
51 */ 51 */
52#define MAXQUOTAS 2 52#define MAXQUOTAS 2
53#define USRQUOTA 0 /* element used for user quotas */ 53#define USRQUOTA 0 /* element used for user quotas */
54#define GRPQUOTA 1 /* element used for group quotas */ 54#define GRPQUOTA 1 /* element used for group quotas */
55 55
56 56
57#if !defined(HAVE_NBTOOL_CONFIG_H) 57#if !defined(HAVE_NBTOOL_CONFIG_H)
58#include <quota/quotaprop.h> 58#include <sys/quota.h>
59__inline static int __unused 59__inline static int __unused
60ufsclass2qtype(int class) 60quota_idtype_to_ufs(int idtype)
61{ 61{
62 switch(class) { 62 switch (idtype) {
63 case QUOTA_CLASS_USER: 63 case QUOTA_IDTYPE_USER:
64 return USRQUOTA; 64 return USRQUOTA;
65 case QUOTA_CLASS_GROUP: 65 case QUOTA_IDTYPE_GROUP:
66 return GRPQUOTA; 66 return GRPQUOTA;
67 default: 67 default:
68 return -1; 68 return -1;
69 } 69 }
70} 70}
71 71
72static __inline int __unused 72static __inline int __unused
73qtype2ufsclass(int type) 73quota_idtype_from_ufs(int ufstype)
74{ 74{
75 switch(type) { 75 switch (ufstype) {
76 case USRQUOTA: 76 case USRQUOTA:
77 return QUOTA_CLASS_USER; 77 return QUOTA_IDTYPE_USER;
78 case GRPQUOTA: 78 case GRPQUOTA:
79 return QUOTA_CLASS_GROUP; 79 return QUOTA_IDTYPE_GROUP;
80 default: 80 default:
81 return -1; 81 return -1;
82 } 82 }
83} 83}
84#endif /* !defined(HAVE_NBTOOL_CONFIG_H) */ 84#endif /* !defined(HAVE_NBTOOL_CONFIG_H) */
85 85
86#ifdef _KERNEL 86#ifdef _KERNEL
87 87
88#include <sys/cdefs.h> 88#include <sys/cdefs.h>
89 89
90__BEGIN_DECLS 90__BEGIN_DECLS
91void dqinit(void); 91void dqinit(void);
92void dqreinit(void); 92void dqreinit(void);
93void dqdone(void); 93void dqdone(void);
94__END_DECLS 94__END_DECLS
95#endif /* _KERNEL */ 95#endif /* _KERNEL */
96 96
97#endif /* !_UFS_UFS_QUOTA_H_ */ 97#endif /* !_UFS_UFS_QUOTA_H_ */

cvs diff -r1.42 -r1.43 src/usr.sbin/edquota/edquota.c (switch to unified diff)

--- src/usr.sbin/edquota/edquota.c 2012/01/29 06:23:20 1.42
+++ src/usr.sbin/edquota/edquota.c 2012/01/29 07:16:00 1.43
@@ -1,1217 +1,1217 @@ @@ -1,1217 +1,1217 @@
1/* $NetBSD: edquota.c,v 1.42 2012/01/29 06:23:20 dholland Exp $ */ 1/* $NetBSD: edquota.c,v 1.43 2012/01/29 07:16:00 dholland Exp $ */
2/* 2/*
3 * Copyright (c) 1980, 1990, 1993 3 * Copyright (c) 1980, 1990, 1993
4 * The Regents of the University of California. All rights reserved. 4 * The Regents of the University of California. All rights reserved.
5 * 5 *
6 * This code is derived from software contributed to Berkeley by 6 * This code is derived from software contributed to Berkeley by
7 * Robert Elz at The University of Melbourne. 7 * Robert Elz at The University of Melbourne.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the University nor the names of its contributors 17 * 3. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software 18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 19 * without specific prior written permission.
20 * 20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE. 31 * SUCH DAMAGE.
32 */ 32 */
33 33
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35#ifndef lint 35#ifndef lint
36__COPYRIGHT("@(#) Copyright (c) 1980, 1990, 1993\ 36__COPYRIGHT("@(#) Copyright (c) 1980, 1990, 1993\
37 The Regents of the University of California. All rights reserved."); 37 The Regents of the University of California. All rights reserved.");
38#endif /* not lint */ 38#endif /* not lint */
39 39
40#ifndef lint 40#ifndef lint
41#if 0 41#if 0
42static char sccsid[] = "from: @(#)edquota.c 8.3 (Berkeley) 4/27/95"; 42static char sccsid[] = "from: @(#)edquota.c 8.3 (Berkeley) 4/27/95";
43#else 43#else
44__RCSID("$NetBSD: edquota.c,v 1.42 2012/01/29 06:23:20 dholland Exp $"); 44__RCSID("$NetBSD: edquota.c,v 1.43 2012/01/29 07:16:00 dholland Exp $");
45#endif 45#endif
46#endif /* not lint */ 46#endif /* not lint */
47 47
48/* 48/*
49 * Disk quota editor. 49 * Disk quota editor.
50 */ 50 */
51#include <sys/param.h> 51#include <sys/param.h>
52#include <sys/stat.h> 52#include <sys/stat.h>
53#include <sys/file.h> 53#include <sys/file.h>
54#include <sys/wait.h> 54#include <sys/wait.h>
55#include <sys/queue.h> 55#include <sys/queue.h>
56#include <sys/types.h> 56#include <sys/types.h>
57#include <sys/statvfs.h> 57#include <sys/statvfs.h>
58 58
59#include <quota.h> 59#include <quota.h>
60#include <quota/quotaprop.h> 60#include <quota/quotaprop.h>
61#include <quota/quota.h> 61#include <quota/quota.h>
62#include <ufs/ufs/quota1.h> 62#include <ufs/ufs/quota1.h>
63#include <sys/quota.h> 63#include <sys/quota.h>
64 64
65#include <assert.h> 65#include <assert.h>
66#include <err.h> 66#include <err.h>
67#include <errno.h> 67#include <errno.h>
68#include <fstab.h> 68#include <fstab.h>
69#include <pwd.h> 69#include <pwd.h>
70#include <grp.h> 70#include <grp.h>
71#include <ctype.h> 71#include <ctype.h>
72#include <signal.h> 72#include <signal.h>
73#include <stdbool.h> 73#include <stdbool.h>
74#include <stdio.h> 74#include <stdio.h>
75#include <stdlib.h> 75#include <stdlib.h>
76#include <string.h> 76#include <string.h>
77#include <unistd.h> 77#include <unistd.h>
78 78
79#include "printquota.h" 79#include "printquota.h"
80#include "getvfsquota.h" 80#include "getvfsquota.h"
81#include "quotautil.h" 81#include "quotautil.h"
82 82
83#include "pathnames.h" 83#include "pathnames.h"
84 84
85static const char *quotagroup = QUOTAGROUP; 85static const char *quotagroup = QUOTAGROUP;
86 86
87#define MAX_TMPSTR (100+MAXPATHLEN) 87#define MAX_TMPSTR (100+MAXPATHLEN)
88 88
89/* flags for quotause */ 89/* flags for quotause */
90#define FOUND 0x01 90#define FOUND 0x01
91#define QUOTA2 0x02 91#define QUOTA2 0x02
92#define DEFAULT 0x04 92#define DEFAULT 0x04
93 93
94struct quotause { 94struct quotause {
95 struct quotause *next; 95 struct quotause *next;
96 long flags; 96 long flags;
97 struct quotaval qv[QUOTA_NLIMITS]; 97 struct quotaval qv[QUOTA_NLIMITS];
98 char fsname[MAXPATHLEN + 1]; 98 char fsname[MAXPATHLEN + 1];
99 char *qfname; 99 char *qfname;
100}; 100};
101 101
102struct quotalist { 102struct quotalist {
103 struct quotause *head; 103 struct quotause *head;
104 struct quotause *tail; 104 struct quotause *tail;
105}; 105};
106 106
107static void usage(void) __dead; 107static void usage(void) __dead;
108 108
109static int Hflag = 0; 109static int Hflag = 0;
110static int Dflag = 0; 110static int Dflag = 0;
111 111
112/* more compact form of constants */ 112/* more compact form of constants */
113#define QL_BLK QUOTA_LIMIT_BLOCK 113#define QL_BLK QUOTA_LIMIT_BLOCK
114#define QL_FL QUOTA_LIMIT_FILE 114#define QL_FL QUOTA_LIMIT_FILE
115 115
116//////////////////////////////////////////////////////////// 116////////////////////////////////////////////////////////////
117// support code 117// support code
118 118
119/* 119/*
120 * This routine converts a name for a particular quota class to 120 * This routine converts a name for a particular quota class to
121 * an identifier. This routine must agree with the kernel routine 121 * an identifier. This routine must agree with the kernel routine
122 * getinoquota as to the interpretation of quota classes. 122 * getinoquota as to the interpretation of quota classes.
123 */ 123 */
124static int 124static int
125getidbyname(const char *name, int idtype) 125getidbyname(const char *name, int idtype)
126{ 126{
127 struct passwd *pw; 127 struct passwd *pw;
128 struct group *gr; 128 struct group *gr;
129 129
130 if (alldigits(name)) 130 if (alldigits(name))
131 return atoi(name); 131 return atoi(name);
132 switch (idtype) { 132 switch (idtype) {
133 case QUOTA_IDTYPE_USER: 133 case QUOTA_IDTYPE_USER:
134 if ((pw = getpwnam(name)) != NULL) 134 if ((pw = getpwnam(name)) != NULL)
135 return pw->pw_uid; 135 return pw->pw_uid;
136 warnx("%s: no such user", name); 136 warnx("%s: no such user", name);
137 break; 137 break;
138 case QUOTA_IDTYPE_GROUP: 138 case QUOTA_IDTYPE_GROUP:
139 if ((gr = getgrnam(name)) != NULL) 139 if ((gr = getgrnam(name)) != NULL)
140 return gr->gr_gid; 140 return gr->gr_gid;
141 warnx("%s: no such group", name); 141 warnx("%s: no such group", name);
142 break; 142 break;
143 default: 143 default:
144 warnx("%d: unknown quota type", idtype); 144 warnx("%d: unknown quota type", idtype);
145 break; 145 break;
146 } 146 }
147 sleep(1); 147 sleep(1);
148 return -1; 148 return -1;
149} 149}
150 150
151//////////////////////////////////////////////////////////// 151////////////////////////////////////////////////////////////
152// quotause operations 152// quotause operations
153 153
154/* 154/*
155 * Create an empty quotause structure. 155 * Create an empty quotause structure.
156 */ 156 */
157static struct quotause * 157static struct quotause *
158quotause_create(void) 158quotause_create(void)
159{ 159{
160 struct quotause *qup; 160 struct quotause *qup;
161 161
162 qup = malloc(sizeof(*qup)); 162 qup = malloc(sizeof(*qup));
163 if (qup == NULL) { 163 if (qup == NULL) {
164 err(1, "malloc"); 164 err(1, "malloc");
165 } 165 }
166 166
167 qup->next = NULL; 167 qup->next = NULL;
168 qup->flags = 0; 168 qup->flags = 0;
169 memset(qup->qv, 0, sizeof(qup->qv)); 169 memset(qup->qv, 0, sizeof(qup->qv));
170 qup->fsname[0] = '\0'; 170 qup->fsname[0] = '\0';
171 qup->qfname = NULL; 171 qup->qfname = NULL;
172 172
173 return qup; 173 return qup;
174} 174}
175 175
176/* 176/*
177 * Free a quotause structure. 177 * Free a quotause structure.
178 */ 178 */
179static void 179static void
180quotause_destroy(struct quotause *qup) 180quotause_destroy(struct quotause *qup)
181{ 181{
182 free(qup->qfname); 182 free(qup->qfname);
183 free(qup); 183 free(qup);
184} 184}
185 185
186//////////////////////////////////////////////////////////// 186////////////////////////////////////////////////////////////
187// quotalist operations 187// quotalist operations
188 188
189/* 189/*
190 * Create a quotause list. 190 * Create a quotause list.
191 */ 191 */
192static struct quotalist * 192static struct quotalist *
193quotalist_create(void) 193quotalist_create(void)
194{ 194{
195 struct quotalist *qlist; 195 struct quotalist *qlist;
196 196
197 qlist = malloc(sizeof(*qlist)); 197 qlist = malloc(sizeof(*qlist));
198 if (qlist == NULL) { 198 if (qlist == NULL) {
199 err(1, "malloc"); 199 err(1, "malloc");
200 } 200 }
201 201
202 qlist->head = NULL; 202 qlist->head = NULL;
203 qlist->tail = NULL; 203 qlist->tail = NULL;
204 204
205 return qlist; 205 return qlist;
206} 206}
207 207
208/* 208/*
209 * Free a list of quotause structures. 209 * Free a list of quotause structures.
210 */ 210 */
211static void 211static void
212quotalist_destroy(struct quotalist *qlist) 212quotalist_destroy(struct quotalist *qlist)
213{ 213{
214 struct quotause *qup, *nextqup; 214 struct quotause *qup, *nextqup;
215 215
216 for (qup = qlist->head; qup; qup = nextqup) { 216 for (qup = qlist->head; qup; qup = nextqup) {
217 nextqup = qup->next; 217 nextqup = qup->next;
218 quotause_destroy(qup); 218 quotause_destroy(qup);
219 } 219 }
220 free(qlist); 220 free(qlist);
221} 221}
222 222
223static bool 223static bool
224quotalist_empty(struct quotalist *qlist) 224quotalist_empty(struct quotalist *qlist)
225{ 225{
226 return qlist->head == NULL; 226 return qlist->head == NULL;
227} 227}
228 228
229static void 229static void
230quotalist_append(struct quotalist *qlist, struct quotause *qup) 230quotalist_append(struct quotalist *qlist, struct quotause *qup)
231{ 231{
232 /* should not already be on a list */ 232 /* should not already be on a list */
233 assert(qup->next == NULL); 233 assert(qup->next == NULL);
234 234
235 if (qlist->head == NULL) { 235 if (qlist->head == NULL) {
236 qlist->head = qup; 236 qlist->head = qup;
237 } else { 237 } else {
238 qlist->tail->next = qup; 238 qlist->tail->next = qup;
239 } 239 }
240 qlist->tail = qup; 240 qlist->tail = qup;
241} 241}
242 242
243//////////////////////////////////////////////////////////// 243////////////////////////////////////////////////////////////
244// ffs quota v1 244// ffs quota v1
245 245
246static void 246static void
247putprivs1(uint32_t id, int idtype, struct quotause *qup) 247putprivs1(uint32_t id, int idtype, struct quotause *qup)
248{ 248{
249 struct dqblk dqblk; 249 struct dqblk dqblk;
250 int fd; 250 int fd;
251 251
252 quotavals_to_dqblk(&qup->qv[QUOTA_LIMIT_BLOCK], 252 quotavals_to_dqblk(&qup->qv[QUOTA_LIMIT_BLOCK],
253 &qup->qv[QUOTA_LIMIT_FILE], 253 &qup->qv[QUOTA_LIMIT_FILE],
254 &dqblk); 254 &dqblk);
255 assert((qup->flags & DEFAULT) == 0); 255 assert((qup->flags & DEFAULT) == 0);
256 256
257 if ((fd = open(qup->qfname, O_WRONLY)) < 0) { 257 if ((fd = open(qup->qfname, O_WRONLY)) < 0) {
258 warnx("open `%s'", qup->qfname); 258 warnx("open `%s'", qup->qfname);
259 } else { 259 } else {
260 (void)lseek(fd, 260 (void)lseek(fd,
261 (off_t)(id * (long)sizeof (struct dqblk)), 261 (off_t)(id * (long)sizeof (struct dqblk)),
262 SEEK_SET); 262 SEEK_SET);
263 if (write(fd, &dqblk, sizeof (struct dqblk)) != 263 if (write(fd, &dqblk, sizeof (struct dqblk)) !=
264 sizeof (struct dqblk)) 264 sizeof (struct dqblk))
265 warnx("writing `%s'", qup->qfname); 265 warnx("writing `%s'", qup->qfname);
266 close(fd); 266 close(fd);
267 } 267 }
268} 268}
269 269
270static struct quotause * 270static struct quotause *
271getprivs1(long id, int idtype, const char *filesys) 271getprivs1(long id, int idtype, const char *filesys)
272{ 272{
273 struct fstab *fs; 273 struct fstab *fs;
274 char qfpathname[MAXPATHLEN]; 274 char qfpathname[MAXPATHLEN];
275 struct quotause *qup; 275 struct quotause *qup;
276 struct dqblk dqblk; 276 struct dqblk dqblk;
277 int fd; 277 int fd;
278 278
279 setfsent(); 279 setfsent();
280 while ((fs = getfsent()) != NULL) { 280 while ((fs = getfsent()) != NULL) {
281 if (strcmp(fs->fs_vfstype, "ffs")) 281 if (strcmp(fs->fs_vfstype, "ffs"))
282 continue; 282 continue;
283 if (strcmp(fs->fs_spec, filesys) == 0 || 283 if (strcmp(fs->fs_spec, filesys) == 0 ||
284 strcmp(fs->fs_file, filesys) == 0) 284 strcmp(fs->fs_file, filesys) == 0)
285 break; 285 break;
286 } 286 }
287 if (fs == NULL) 287 if (fs == NULL)
288 return NULL; 288 return NULL;
289 289
290 if (!hasquota(qfpathname, sizeof(qfpathname), fs, 290 if (!hasquota(qfpathname, sizeof(qfpathname), fs,
291 ufsclass2qtype(idtype))) 291 quota_idtype_to_ufs(idtype)))
292 return NULL; 292 return NULL;
293 293
294 qup = quotause_create(); 294 qup = quotause_create();
295 strcpy(qup->fsname, fs->fs_file); 295 strcpy(qup->fsname, fs->fs_file);
296 if ((fd = open(qfpathname, O_RDONLY)) < 0) { 296 if ((fd = open(qfpathname, O_RDONLY)) < 0) {
297 fd = open(qfpathname, O_RDWR|O_CREAT, 0640); 297 fd = open(qfpathname, O_RDWR|O_CREAT, 0640);
298 if (fd < 0 && errno != ENOENT) { 298 if (fd < 0 && errno != ENOENT) {
299 warnx("open `%s'", qfpathname); 299 warnx("open `%s'", qfpathname);
300 quotause_destroy(qup); 300 quotause_destroy(qup);
301 return NULL; 301 return NULL;
302 } 302 }
303 warnx("Creating quota file %s", qfpathname); 303 warnx("Creating quota file %s", qfpathname);
304 sleep(3); 304 sleep(3);
305 (void)fchown(fd, getuid(), 305 (void)fchown(fd, getuid(),
306 getidbyname(quotagroup, QUOTA_CLASS_GROUP)); 306 getidbyname(quotagroup, QUOTA_CLASS_GROUP));
307 (void)fchmod(fd, 0640); 307 (void)fchmod(fd, 0640);
308 } 308 }
309 (void)lseek(fd, (off_t)(id * sizeof(struct dqblk)), 309 (void)lseek(fd, (off_t)(id * sizeof(struct dqblk)),
310 SEEK_SET); 310 SEEK_SET);
311 switch (read(fd, &dqblk, sizeof(struct dqblk))) { 311 switch (read(fd, &dqblk, sizeof(struct dqblk))) {
312 case 0: /* EOF */ 312 case 0: /* EOF */
313 /* 313 /*
314 * Convert implicit 0 quota (EOF) 314 * Convert implicit 0 quota (EOF)
315 * into an explicit one (zero'ed dqblk) 315 * into an explicit one (zero'ed dqblk)
316 */ 316 */
317 memset(&dqblk, 0, sizeof(struct dqblk)); 317 memset(&dqblk, 0, sizeof(struct dqblk));
318 break; 318 break;
319 319
320 case sizeof(struct dqblk): /* OK */ 320 case sizeof(struct dqblk): /* OK */
321 break; 321 break;
322 322
323 default: /* ERROR */ 323 default: /* ERROR */
324 warn("read error in `%s'", qfpathname); 324 warn("read error in `%s'", qfpathname);
325 close(fd); 325 close(fd);
326 quotause_destroy(qup); 326 quotause_destroy(qup);
327 return NULL; 327 return NULL;
328 } 328 }
329 close(fd); 329 close(fd);
330 qup->qfname = qfpathname; 330 qup->qfname = qfpathname;
331 endfsent(); 331 endfsent();
332 dqblk_to_quotavals(&dqblk, 332 dqblk_to_quotavals(&dqblk,
333 &qup->qv[QUOTA_LIMIT_BLOCK], 333 &qup->qv[QUOTA_LIMIT_BLOCK],
334 &qup->qv[QUOTA_LIMIT_FILE]); 334 &qup->qv[QUOTA_LIMIT_FILE]);
335 return qup; 335 return qup;
336} 336}
337 337
338//////////////////////////////////////////////////////////// 338////////////////////////////////////////////////////////////
339// ffs quota v2 339// ffs quota v2
340 340
341static struct quotause * 341static struct quotause *
342getprivs2(long id, int idtype, const char *filesys, int defaultq) 342getprivs2(long id, int idtype, const char *filesys, int defaultq)
343{ 343{
344 struct quotause *qup; 344 struct quotause *qup;
345 int8_t version; 345 int8_t version;
346 346
347 qup = quotause_create(); 347 qup = quotause_create();
348 strcpy(qup->fsname, filesys); 348 strcpy(qup->fsname, filesys);
349 if (defaultq) 349 if (defaultq)
350 qup->flags |= DEFAULT; 350 qup->flags |= DEFAULT;
351 if (!getvfsquota(filesys, qup->qv, &version, 351 if (!getvfsquota(filesys, qup->qv, &version,
352 id, idtype, defaultq, Dflag)) { 352 id, idtype, defaultq, Dflag)) {
353 /* no entry, get default entry */ 353 /* no entry, get default entry */
354 if (!getvfsquota(filesys, qup->qv, &version, 354 if (!getvfsquota(filesys, qup->qv, &version,
355 id, idtype, 1, Dflag)) { 355 id, idtype, 1, Dflag)) {
356 free(qup); 356 free(qup);
357 return NULL; 357 return NULL;
358 } 358 }
359 } 359 }
360 if (version == 2) 360 if (version == 2)
361 qup->flags |= QUOTA2; 361 qup->flags |= QUOTA2;
362 return qup; 362 return qup;
363} 363}
364 364
365static void 365static void
366putprivs2(uint32_t id, int idtype, struct quotause *qup) 366putprivs2(uint32_t id, int idtype, struct quotause *qup)
367{ 367{
368 struct quotahandle *qh; 368 struct quotahandle *qh;
369 struct quotakey qk; 369 struct quotakey qk;
370 char idname[32]; 370 char idname[32];
371 371
372 if (qup->flags & DEFAULT) { 372 if (qup->flags & DEFAULT) {
373 snprintf(idname, sizeof(idname), "%s default", 373 snprintf(idname, sizeof(idname), "%s default",
374 idtype == QUOTA_IDTYPE_USER ? "user" : "group"); 374 idtype == QUOTA_IDTYPE_USER ? "user" : "group");
375 id = QUOTA_DEFAULTID; 375 id = QUOTA_DEFAULTID;
376 } else { 376 } else {
377 snprintf(idname, sizeof(idname), "%s %u", 377 snprintf(idname, sizeof(idname), "%s %u",
378 idtype == QUOTA_IDTYPE_USER ? "uid" : "gid", id); 378 idtype == QUOTA_IDTYPE_USER ? "uid" : "gid", id);
379 } 379 }
380 380
381 qh = quota_open(qup->fsname); 381 qh = quota_open(qup->fsname);
382 if (qh == NULL) { 382 if (qh == NULL) {
383 err(1, "%s: quota_open", qup->fsname); 383 err(1, "%s: quota_open", qup->fsname);
384 } 384 }
385 385
386 qk.qk_idtype = idtype; 386 qk.qk_idtype = idtype;
387 qk.qk_id = id; 387 qk.qk_id = id;
388 qk.qk_objtype = QUOTA_OBJTYPE_BLOCKS; 388 qk.qk_objtype = QUOTA_OBJTYPE_BLOCKS;
389 if (quota_put(qh, &qk, &qup->qv[QL_BLK])) { 389 if (quota_put(qh, &qk, &qup->qv[QL_BLK])) {
390 err(1, "%s: quota_put (%s blocks)", qup->fsname, idname); 390 err(1, "%s: quota_put (%s blocks)", qup->fsname, idname);
391 } 391 }
392 392
393 qk.qk_idtype = idtype; 393 qk.qk_idtype = idtype;
394 qk.qk_id = id; 394 qk.qk_id = id;
395 qk.qk_objtype = QUOTA_OBJTYPE_FILES; 395 qk.qk_objtype = QUOTA_OBJTYPE_FILES;
396 if (quota_put(qh, &qk, &qup->qv[QL_FL])) { 396 if (quota_put(qh, &qk, &qup->qv[QL_FL])) {
397 err(1, "%s: quota_put (%s files)", qup->fsname, idname); 397 err(1, "%s: quota_put (%s files)", qup->fsname, idname);
398 } 398 }
399 399
400 quota_close(qh); 400 quota_close(qh);
401} 401}
402 402
403//////////////////////////////////////////////////////////// 403////////////////////////////////////////////////////////////
404// quota format switch 404// quota format switch
405 405
406/* 406/*
407 * Collect the requested quota information. 407 * Collect the requested quota information.
408 */ 408 */
409static struct quotalist * 409static struct quotalist *
410getprivs(long id, int defaultq, int idtype, const char *filesys) 410getprivs(long id, int defaultq, int idtype, const char *filesys)
411{ 411{
412 struct statvfs *fst; 412 struct statvfs *fst;
413 int nfst, i; 413 int nfst, i;
414 struct quotalist *qlist; 414 struct quotalist *qlist;
415 struct quotause *qup; 415 struct quotause *qup;
416 416
417 qlist = quotalist_create(); 417 qlist = quotalist_create();
418 418
419 nfst = getmntinfo(&fst, MNT_WAIT); 419 nfst = getmntinfo(&fst, MNT_WAIT);
420 if (nfst == 0) 420 if (nfst == 0)
421 errx(1, "no filesystems mounted!"); 421 errx(1, "no filesystems mounted!");
422 422
423 for (i = 0; i < nfst; i++) { 423 for (i = 0; i < nfst; i++) {
424 if ((fst[i].f_flag & ST_QUOTA) == 0) 424 if ((fst[i].f_flag & ST_QUOTA) == 0)
425 continue; 425 continue;
426 if (filesys && 426 if (filesys &&
427 strcmp(fst[i].f_mntonname, filesys) != 0 && 427 strcmp(fst[i].f_mntonname, filesys) != 0 &&
428 strcmp(fst[i].f_mntfromname, filesys) != 0) 428 strcmp(fst[i].f_mntfromname, filesys) != 0)
429 continue; 429 continue;
430 qup = getprivs2(id, idtype, fst[i].f_mntonname, defaultq); 430 qup = getprivs2(id, idtype, fst[i].f_mntonname, defaultq);
431 if (qup == NULL) { 431 if (qup == NULL) {
432 /* 432 /*
433 * XXX: returning NULL is totally wrong. On 433 * XXX: returning NULL is totally wrong. On
434 * serious error, abort; on minor error, warn 434 * serious error, abort; on minor error, warn
435 * and continue. 435 * and continue.
436 * 436 *
437 * Note: we cannot warn unconditionally here 437 * Note: we cannot warn unconditionally here
438 * because this case apparently includes "no 438 * because this case apparently includes "no
439 * quota entry on this volume" and that causes 439 * quota entry on this volume" and that causes
440 * the atf tests to fail. Bletch. 440 * the atf tests to fail. Bletch.
441 */ 441 */
442 /*return NULL;*/ 442 /*return NULL;*/
443 /*warnx("getprivs2 failed");*/ 443 /*warnx("getprivs2 failed");*/
444 continue; 444 continue;
445 } 445 }
446 446
447 quotalist_append(qlist, qup); 447 quotalist_append(qlist, qup);
448 } 448 }
449 449
450 if (filesys && quotalist_empty(qlist)) { 450 if (filesys && quotalist_empty(qlist)) {
451 if (defaultq) 451 if (defaultq)
452 errx(1, "no default quota for version 1"); 452 errx(1, "no default quota for version 1");
453 /* if we get there, filesys is not mounted. try the old way */ 453 /* if we get there, filesys is not mounted. try the old way */
454 qup = getprivs1(id, idtype, filesys); 454 qup = getprivs1(id, idtype, filesys);
455 if (qup == NULL) { 455 if (qup == NULL) {
456 /* XXX. see above */ 456 /* XXX. see above */
457 /*return NULL;*/ 457 /*return NULL;*/
458 /*warnx("getprivs1 failed");*/ 458 /*warnx("getprivs1 failed");*/
459 return qlist; 459 return qlist;
460 } 460 }
461 quotalist_append(qlist, qup); 461 quotalist_append(qlist, qup);
462 } 462 }
463 return qlist; 463 return qlist;
464} 464}
465 465
466/* 466/*
467 * Store the requested quota information. 467 * Store the requested quota information.
468 */ 468 */
469static void 469static void
470putprivs(uint32_t id, int idtype, struct quotalist *qlist) 470putprivs(uint32_t id, int idtype, struct quotalist *qlist)
471{ 471{
472 struct quotause *qup; 472 struct quotause *qup;
473 473
474 for (qup = qlist->head; qup; qup = qup->next) { 474 for (qup = qlist->head; qup; qup = qup->next) {
475 if (qup->qfname == NULL) 475 if (qup->qfname == NULL)
476 putprivs2(id, idtype, qup); 476 putprivs2(id, idtype, qup);
477 else 477 else
478 putprivs1(id, idtype, qup); 478 putprivs1(id, idtype, qup);
479 } 479 }
480} 480}
481 481
482static void 482static void
483clearpriv(int argc, char **argv, const char *filesys, int idtype) 483clearpriv(int argc, char **argv, const char *filesys, int idtype)
484{ 484{
485 struct statvfs *fst; 485 struct statvfs *fst;
486 int nfst, i; 486 int nfst, i;
487 int id; 487 int id;
488 id_t *ids; 488 id_t *ids;
489 unsigned nids, maxids, j; 489 unsigned nids, maxids, j;
490 struct quotahandle *qh; 490 struct quotahandle *qh;
491 struct quotakey qk; 491 struct quotakey qk;
492 char idname[32]; 492 char idname[32];
493 493
494 maxids = 4; 494 maxids = 4;
495 nids = 0; 495 nids = 0;
496 ids = malloc(maxids * sizeof(ids[0])); 496 ids = malloc(maxids * sizeof(ids[0]));
497 if (ids == NULL) { 497 if (ids == NULL) {
498 err(1, "malloc"); 498 err(1, "malloc");
499 } 499 }
500 500
501 for ( ; argc > 0; argc--, argv++) { 501 for ( ; argc > 0; argc--, argv++) {
502 if ((id = getidbyname(*argv, idtype)) == -1) 502 if ((id = getidbyname(*argv, idtype)) == -1)
503 continue; 503 continue;
504 504
505 if (nids + 1 > maxids) { 505 if (nids + 1 > maxids) {
506 maxids *= 2; 506 maxids *= 2;
507 ids = realloc(ids, maxids * sizeof(ids[0])); 507 ids = realloc(ids, maxids * sizeof(ids[0]));
508 if (ids == NULL) { 508 if (ids == NULL) {
509 err(1, "realloc"); 509 err(1, "realloc");
510 } 510 }
511 } 511 }
512 ids[nids++] = id; 512 ids[nids++] = id;
513 } 513 }
514 514
515 /* now loop over quota-enabled filesystems */ 515 /* now loop over quota-enabled filesystems */
516 nfst = getmntinfo(&fst, MNT_WAIT); 516 nfst = getmntinfo(&fst, MNT_WAIT);
517 if (nfst == 0) 517 if (nfst == 0)
518 errx(1, "no filesystems mounted!"); 518 errx(1, "no filesystems mounted!");
519 519
520 for (i = 0; i < nfst; i++) { 520 for (i = 0; i < nfst; i++) {
521 if ((fst[i].f_flag & ST_QUOTA) == 0) 521 if ((fst[i].f_flag & ST_QUOTA) == 0)
522 continue; 522 continue;
523 if (filesys && strcmp(fst[i].f_mntonname, filesys) != 0 && 523 if (filesys && strcmp(fst[i].f_mntonname, filesys) != 0 &&
524 strcmp(fst[i].f_mntfromname, filesys) != 0) 524 strcmp(fst[i].f_mntfromname, filesys) != 0)
525 continue; 525 continue;
526 526
527 qh = quota_open(fst[i].f_mntonname); 527 qh = quota_open(fst[i].f_mntonname);
528 if (qh == NULL) { 528 if (qh == NULL) {
529 err(1, "%s: quota_open", fst[i].f_mntonname); 529 err(1, "%s: quota_open", fst[i].f_mntonname);
530 } 530 }
531 531
532 for (j = 0; j < nids; j++) { 532 for (j = 0; j < nids; j++) {
533 snprintf(idname, sizeof(idname), "%s %u", 533 snprintf(idname, sizeof(idname), "%s %u",
534 idtype == QUOTA_IDTYPE_USER ?  534 idtype == QUOTA_IDTYPE_USER ?
535 "uid" : "gid", ids[j]); 535 "uid" : "gid", ids[j]);
536 536
537 qk.qk_idtype = idtype; 537 qk.qk_idtype = idtype;
538 qk.qk_id = ids[j]; 538 qk.qk_id = ids[j];
539 qk.qk_objtype = QUOTA_OBJTYPE_BLOCKS; 539 qk.qk_objtype = QUOTA_OBJTYPE_BLOCKS;
540 if (quota_delete(qh, &qk)) { 540 if (quota_delete(qh, &qk)) {
541 err(1, "%s: quota_delete (%s blocks)", 541 err(1, "%s: quota_delete (%s blocks)",
542 fst[i].f_mntonname, idname); 542 fst[i].f_mntonname, idname);
543 } 543 }
544 544
545 qk.qk_idtype = idtype; 545 qk.qk_idtype = idtype;
546 qk.qk_id = ids[j]; 546 qk.qk_id = ids[j];
547 qk.qk_objtype = QUOTA_OBJTYPE_FILES; 547 qk.qk_objtype = QUOTA_OBJTYPE_FILES;
548 if (quota_delete(qh, &qk)) { 548 if (quota_delete(qh, &qk)) {
549 if (errno == ENOENT) { 549 if (errno == ENOENT) {
550 /* 550 /*
551 * XXX ignore this case; due 551 * XXX ignore this case; due
552 * to a weakness in the quota 552 * to a weakness in the quota
553 * proplib interface it can 553 * proplib interface it can
554 * appear spuriously. 554 * appear spuriously.
555 */ 555 */
556 } else { 556 } else {
557 err(1, "%s: quota_delete (%s files)", 557 err(1, "%s: quota_delete (%s files)",
558 fst[i].f_mntonname, idname); 558 fst[i].f_mntonname, idname);
559 } 559 }
560 } 560 }
561 } 561 }
562 562
563 quota_close(qh); 563 quota_close(qh);
564 } 564 }
565 565
566 free(ids); 566 free(ids);
567} 567}
568 568
569//////////////////////////////////////////////////////////// 569////////////////////////////////////////////////////////////
570// editor 570// editor
571 571
572/* 572/*
573 * Take a list of privileges and get it edited. 573 * Take a list of privileges and get it edited.
574 */ 574 */
575static int 575static int
576editit(const char *ltmpfile) 576editit(const char *ltmpfile)
577{ 577{
578 pid_t pid; 578 pid_t pid;
579 int lst; 579 int lst;
580 char p[MAX_TMPSTR]; 580 char p[MAX_TMPSTR];
581 const char *ed; 581 const char *ed;
582 sigset_t s, os; 582 sigset_t s, os;
583 583
584 sigemptyset(&s); 584 sigemptyset(&s);
585 sigaddset(&s, SIGINT); 585 sigaddset(&s, SIGINT);
586 sigaddset(&s, SIGQUIT); 586 sigaddset(&s, SIGQUIT);
587 sigaddset(&s, SIGHUP); 587 sigaddset(&s, SIGHUP);
588 if (sigprocmask(SIG_BLOCK, &s, &os) == -1) 588 if (sigprocmask(SIG_BLOCK, &s, &os) == -1)
589 err(1, "sigprocmask"); 589 err(1, "sigprocmask");
590top: 590top:
591 switch ((pid = fork())) { 591 switch ((pid = fork())) {
592 case -1: 592 case -1:
593 if (errno == EPROCLIM) { 593 if (errno == EPROCLIM) {
594 warnx("You have too many processes"); 594 warnx("You have too many processes");
595 return 0; 595 return 0;
596 } 596 }
597 if (errno == EAGAIN) { 597 if (errno == EAGAIN) {
598 sleep(1); 598 sleep(1);
599 goto top; 599 goto top;
600 } 600 }
601 warn("fork"); 601 warn("fork");
602 return 0; 602 return 0;
603 case 0: 603 case 0:
604 if (sigprocmask(SIG_SETMASK, &os, NULL) == -1) 604 if (sigprocmask(SIG_SETMASK, &os, NULL) == -1)
605 err(1, "sigprocmask"); 605 err(1, "sigprocmask");
606 setgid(getgid()); 606 setgid(getgid());
607 setuid(getuid()); 607 setuid(getuid());
608 if ((ed = getenv("EDITOR")) == (char *)0) 608 if ((ed = getenv("EDITOR")) == (char *)0)
609 ed = _PATH_VI; 609 ed = _PATH_VI;
610 if (strlen(ed) + strlen(ltmpfile) + 2 >= MAX_TMPSTR) { 610 if (strlen(ed) + strlen(ltmpfile) + 2 >= MAX_TMPSTR) {
611 errx(1, "%s", "editor or filename too long"); 611 errx(1, "%s", "editor or filename too long");
612 } 612 }
613 snprintf(p, sizeof(p), "%s %s", ed, ltmpfile); 613 snprintf(p, sizeof(p), "%s %s", ed, ltmpfile);
614 execlp(_PATH_BSHELL, _PATH_BSHELL, "-c", p, NULL); 614 execlp(_PATH_BSHELL, _PATH_BSHELL, "-c", p, NULL);
615 err(1, "%s", ed); 615 err(1, "%s", ed);
616 default: 616 default:
617 if (waitpid(pid, &lst, 0) == -1) 617 if (waitpid(pid, &lst, 0) == -1)
618 err(1, "waitpid"); 618 err(1, "waitpid");
619 if (sigprocmask(SIG_SETMASK, &os, NULL) == -1) 619 if (sigprocmask(SIG_SETMASK, &os, NULL) == -1)
620 err(1, "sigprocmask"); 620 err(1, "sigprocmask");
621 if (!WIFEXITED(lst) || WEXITSTATUS(lst) != 0) 621 if (!WIFEXITED(lst) || WEXITSTATUS(lst) != 0)
622 return 0; 622 return 0;
623 return 1; 623 return 1;
624 } 624 }
625} 625}
626 626
627/* 627/*
628 * Convert a quotause list to an ASCII file. 628 * Convert a quotause list to an ASCII file.
629 */ 629 */
630static int 630static int
631writeprivs(struct quotalist *qlist, int outfd, const char *name, 631writeprivs(struct quotalist *qlist, int outfd, const char *name,
632 int idtype) 632 int idtype)
633{ 633{
634 struct quotause *qup; 634 struct quotause *qup;
635 FILE *fd; 635 FILE *fd;
636 char b0[32], b1[32], b2[32], b3[32]; 636 char b0[32], b1[32], b2[32], b3[32];
637 637
638 (void)ftruncate(outfd, 0); 638 (void)ftruncate(outfd, 0);
639 (void)lseek(outfd, (off_t)0, SEEK_SET); 639 (void)lseek(outfd, (off_t)0, SEEK_SET);
640 if ((fd = fdopen(dup(outfd), "w")) == NULL) 640 if ((fd = fdopen(dup(outfd), "w")) == NULL)
641 errx(1, "fdopen"); 641 errx(1, "fdopen");
642 if (name == NULL) { 642 if (name == NULL) {
643 fprintf(fd, "Default %s quotas:\n", 643 fprintf(fd, "Default %s quotas:\n",
644 ufs_quota_class_names[idtype]); 644 ufs_quota_class_names[idtype]);
645 } else { 645 } else {
646 fprintf(fd, "Quotas for %s %s:\n", 646 fprintf(fd, "Quotas for %s %s:\n",
647 ufs_quota_class_names[idtype], name); 647 ufs_quota_class_names[idtype], name);
648 } 648 }
649 for (qup = qlist->head; qup; qup = qup->next) { 649 for (qup = qlist->head; qup; qup = qup->next) {
650 struct quotaval *q = qup->qv; 650 struct quotaval *q = qup->qv;
651 fprintf(fd, "%s (version %d):\n", 651 fprintf(fd, "%s (version %d):\n",
652 qup->fsname, (qup->flags & QUOTA2) ? 2 : 1); 652 qup->fsname, (qup->flags & QUOTA2) ? 2 : 1);
653 if ((qup->flags & DEFAULT) == 0 || (qup->flags & QUOTA2) != 0) { 653 if ((qup->flags & DEFAULT) == 0 || (qup->flags & QUOTA2) != 0) {
654 fprintf(fd, "\tblocks in use: %s, " 654 fprintf(fd, "\tblocks in use: %s, "
655 "limits (soft = %s, hard = %s", 655 "limits (soft = %s, hard = %s",
656 intprt(b1, 21, q[QL_BLK].qv_usage, 656 intprt(b1, 21, q[QL_BLK].qv_usage,
657 HN_NOSPACE | HN_B, Hflag),  657 HN_NOSPACE | HN_B, Hflag),
658 intprt(b2, 21, q[QL_BLK].qv_softlimit, 658 intprt(b2, 21, q[QL_BLK].qv_softlimit,
659 HN_NOSPACE | HN_B, Hflag), 659 HN_NOSPACE | HN_B, Hflag),
660 intprt(b3, 21, q[QL_BLK].qv_hardlimit, 660 intprt(b3, 21, q[QL_BLK].qv_hardlimit,
661 HN_NOSPACE | HN_B, Hflag)); 661 HN_NOSPACE | HN_B, Hflag));
662 if (qup->flags & QUOTA2) 662 if (qup->flags & QUOTA2)
663 fprintf(fd, ", "); 663 fprintf(fd, ", ");
664 } else 664 } else
665 fprintf(fd, "\tblocks: ("); 665 fprintf(fd, "\tblocks: (");
666  666
667 if (qup->flags & (QUOTA2|DEFAULT)) { 667 if (qup->flags & (QUOTA2|DEFAULT)) {
668 fprintf(fd, "grace = %s", 668 fprintf(fd, "grace = %s",
669 timepprt(b0, 21, q[QL_BLK].qv_grace, Hflag)); 669 timepprt(b0, 21, q[QL_BLK].qv_grace, Hflag));
670 } 670 }
671 fprintf(fd, ")\n"); 671 fprintf(fd, ")\n");
672 if ((qup->flags & DEFAULT) == 0 || (qup->flags & QUOTA2) != 0) { 672 if ((qup->flags & DEFAULT) == 0 || (qup->flags & QUOTA2) != 0) {
673 fprintf(fd, "\tinodes in use: %s, " 673 fprintf(fd, "\tinodes in use: %s, "
674 "limits (soft = %s, hard = %s", 674 "limits (soft = %s, hard = %s",
675 intprt(b1, 21, q[QL_FL].qv_usage, 675 intprt(b1, 21, q[QL_FL].qv_usage,
676 HN_NOSPACE, Hflag), 676 HN_NOSPACE, Hflag),
677 intprt(b2, 21, q[QL_FL].qv_softlimit, 677 intprt(b2, 21, q[QL_FL].qv_softlimit,
678 HN_NOSPACE, Hflag), 678 HN_NOSPACE, Hflag),
679 intprt(b3, 21, q[QL_FL].qv_hardlimit, 679 intprt(b3, 21, q[QL_FL].qv_hardlimit,
680 HN_NOSPACE, Hflag)); 680 HN_NOSPACE, Hflag));
681 if (qup->flags & QUOTA2) 681 if (qup->flags & QUOTA2)
682 fprintf(fd, ", "); 682 fprintf(fd, ", ");
683 } else 683 } else
684 fprintf(fd, "\tinodes: ("); 684 fprintf(fd, "\tinodes: (");
685 685
686 if (qup->flags & (QUOTA2|DEFAULT)) { 686 if (qup->flags & (QUOTA2|DEFAULT)) {
687 fprintf(fd, "grace = %s", 687 fprintf(fd, "grace = %s",
688 timepprt(b0, 21, q[QL_FL].qv_grace, Hflag)); 688 timepprt(b0, 21, q[QL_FL].qv_grace, Hflag));
689 } 689 }
690 fprintf(fd, ")\n"); 690 fprintf(fd, ")\n");
691 } 691 }
692 fclose(fd); 692 fclose(fd);
693 return 1; 693 return 1;
694} 694}
695 695
696/* 696/*
697 * Merge changes to an ASCII file into a quotause list. 697 * Merge changes to an ASCII file into a quotause list.
698 */ 698 */
699static int 699static int
700readprivs(struct quotalist *qlist, int infd, int dflag) 700readprivs(struct quotalist *qlist, int infd, int dflag)
701{ 701{
702 struct quotause *qup; 702 struct quotause *qup;
703 FILE *fd; 703 FILE *fd;
704 int cnt; 704 int cnt;
705 char fsp[BUFSIZ]; 705 char fsp[BUFSIZ];
706 static char line0[BUFSIZ], line1[BUFSIZ], line2[BUFSIZ]; 706 static char line0[BUFSIZ], line1[BUFSIZ], line2[BUFSIZ];
707 static char scurb[BUFSIZ], scuri[BUFSIZ], ssoft[BUFSIZ], shard[BUFSIZ]; 707 static char scurb[BUFSIZ], scuri[BUFSIZ], ssoft[BUFSIZ], shard[BUFSIZ];
708 static char stime[BUFSIZ]; 708 static char stime[BUFSIZ];
709 uint64_t softb, hardb, softi, hardi; 709 uint64_t softb, hardb, softi, hardi;
710 time_t graceb = -1, gracei = -1; 710 time_t graceb = -1, gracei = -1;
711 int version; 711 int version;
712 712
713 (void)lseek(infd, (off_t)0, SEEK_SET); 713 (void)lseek(infd, (off_t)0, SEEK_SET);
714 fd = fdopen(dup(infd), "r"); 714 fd = fdopen(dup(infd), "r");
715 if (fd == NULL) { 715 if (fd == NULL) {
716 warn("Can't re-read temp file"); 716 warn("Can't re-read temp file");
717 return 0; 717 return 0;
718 } 718 }
719 /* 719 /*
720 * Discard title line, then read pairs of lines to process. 720 * Discard title line, then read pairs of lines to process.
721 */ 721 */
722 (void) fgets(line1, sizeof (line1), fd); 722 (void) fgets(line1, sizeof (line1), fd);
723 while (fgets(line0, sizeof (line0), fd) != NULL && 723 while (fgets(line0, sizeof (line0), fd) != NULL &&
724 fgets(line1, sizeof (line2), fd) != NULL && 724 fgets(line1, sizeof (line2), fd) != NULL &&
725 fgets(line2, sizeof (line2), fd) != NULL) { 725 fgets(line2, sizeof (line2), fd) != NULL) {
726 if (sscanf(line0, "%s (version %d):\n", fsp, &version) != 2) { 726 if (sscanf(line0, "%s (version %d):\n", fsp, &version) != 2) {
727 warnx("%s: bad format", line0); 727 warnx("%s: bad format", line0);
728 goto out; 728 goto out;
729 } 729 }
730#define last_char(str) ((str)[strlen(str) - 1]) 730#define last_char(str) ((str)[strlen(str) - 1])
731 if (last_char(line1) != '\n') { 731 if (last_char(line1) != '\n') {
732 warnx("%s:%s: bad format", fsp, line1); 732 warnx("%s:%s: bad format", fsp, line1);
733 goto out; 733 goto out;
734 } 734 }
735 last_char(line1) = '\0'; 735 last_char(line1) = '\0';
736 if (last_char(line2) != '\n') { 736 if (last_char(line2) != '\n') {
737 warnx("%s:%s: bad format", fsp, line2); 737 warnx("%s:%s: bad format", fsp, line2);
738 goto out; 738 goto out;
739 } 739 }
740 last_char(line2) = '\0'; 740 last_char(line2) = '\0';
741 if (dflag && version == 1) { 741 if (dflag && version == 1) {
742 if (sscanf(line1, 742 if (sscanf(line1,
743 "\tblocks: (grace = %s\n", stime) != 1) { 743 "\tblocks: (grace = %s\n", stime) != 1) {
744 warnx("%s:%s: bad format", fsp, line1); 744 warnx("%s:%s: bad format", fsp, line1);
745 goto out; 745 goto out;
746 } 746 }
747 if (last_char(stime) != ')') { 747 if (last_char(stime) != ')') {
748 warnx("%s:%s: bad format", fsp, line1); 748 warnx("%s:%s: bad format", fsp, line1);
749 goto out; 749 goto out;
750 } 750 }
751 last_char(stime) = '\0'; 751 last_char(stime) = '\0';
752 if (timeprd(stime, &graceb) != 0) { 752 if (timeprd(stime, &graceb) != 0) {
753 warnx("%s:%s: bad number", fsp, stime); 753 warnx("%s:%s: bad number", fsp, stime);
754 goto out; 754 goto out;
755 } 755 }
756 if (sscanf(line2, 756 if (sscanf(line2,
757 "\tinodes: (grace = %s\n", stime) != 1) { 757 "\tinodes: (grace = %s\n", stime) != 1) {
758 warnx("%s:%s: bad format", fsp, line2); 758 warnx("%s:%s: bad format", fsp, line2);
759 goto out; 759 goto out;
760 } 760 }
761 if (last_char(stime) != ')') { 761 if (last_char(stime) != ')') {
762 warnx("%s:%s: bad format", fsp, line2); 762 warnx("%s:%s: bad format", fsp, line2);
763 goto out; 763 goto out;
764 } 764 }
765 last_char(stime) = '\0'; 765 last_char(stime) = '\0';
766 if (timeprd(stime, &gracei) != 0) { 766 if (timeprd(stime, &gracei) != 0) {
767 warnx("%s:%s: bad number", fsp, stime); 767 warnx("%s:%s: bad number", fsp, stime);
768 goto out; 768 goto out;
769 } 769 }
770 } else { 770 } else {
771 cnt = sscanf(line1, 771 cnt = sscanf(line1,
772 "\tblocks in use: %s limits (soft = %s hard = %s " 772 "\tblocks in use: %s limits (soft = %s hard = %s "
773 "grace = %s", scurb, ssoft, shard, stime); 773 "grace = %s", scurb, ssoft, shard, stime);
774 if (cnt == 3) { 774 if (cnt == 3) {
775 if (version != 1 || 775 if (version != 1 ||
776 last_char(scurb) != ',' || 776 last_char(scurb) != ',' ||
777 last_char(ssoft) != ',' || 777 last_char(ssoft) != ',' ||
778 last_char(shard) != ')') { 778 last_char(shard) != ')') {
779 warnx("%s:%s: bad format %d", 779 warnx("%s:%s: bad format %d",
780 fsp, line1, cnt); 780 fsp, line1, cnt);
781 goto out; 781 goto out;
782 } 782 }
783 stime[0] = '\0'; 783 stime[0] = '\0';
784 } else if (cnt == 4) { 784 } else if (cnt == 4) {
785 if (version < 2 || 785 if (version < 2 ||
786 last_char(scurb) != ',' || 786 last_char(scurb) != ',' ||
787 last_char(ssoft) != ',' || 787 last_char(ssoft) != ',' ||
788 last_char(shard) != ',' || 788 last_char(shard) != ',' ||
789 last_char(stime) != ')') { 789 last_char(stime) != ')') {
790 warnx("%s:%s: bad format %d", 790 warnx("%s:%s: bad format %d",
791 fsp, line1, cnt); 791 fsp, line1, cnt);
792 goto out; 792 goto out;
793 } 793 }
794 } else { 794 } else {
795 warnx("%s: %s: bad format cnt %d", fsp, line1, 795 warnx("%s: %s: bad format cnt %d", fsp, line1,
796 cnt); 796 cnt);
797 goto out; 797 goto out;
798 } 798 }
799 /* drop last char which is ',' or ')' */ 799 /* drop last char which is ',' or ')' */
800 last_char(scurb) = '\0'; 800 last_char(scurb) = '\0';
801 last_char(ssoft) = '\0'; 801 last_char(ssoft) = '\0';
802 last_char(shard) = '\0'; 802 last_char(shard) = '\0';
803 last_char(stime) = '\0'; 803 last_char(stime) = '\0';
804  804
805 if (intrd(ssoft, &softb, HN_B) != 0) { 805 if (intrd(ssoft, &softb, HN_B) != 0) {
806 warnx("%s:%s: bad number", fsp, ssoft); 806 warnx("%s:%s: bad number", fsp, ssoft);
807 goto out; 807 goto out;
808 } 808 }
809 if (intrd(shard, &hardb, HN_B) != 0) { 809 if (intrd(shard, &hardb, HN_B) != 0) {
810 warnx("%s:%s: bad number", fsp, shard); 810 warnx("%s:%s: bad number", fsp, shard);
811 goto out; 811 goto out;
812 } 812 }
813 if (cnt == 4) { 813 if (cnt == 4) {
814 if (timeprd(stime, &graceb) != 0) { 814 if (timeprd(stime, &graceb) != 0) {
815 warnx("%s:%s: bad number", fsp, stime); 815 warnx("%s:%s: bad number", fsp, stime);
816 goto out; 816 goto out;
817 } 817 }
818 } 818 }
819 819
820 cnt = sscanf(line2, 820 cnt = sscanf(line2,
821 "\tinodes in use: %s limits (soft = %s hard = %s " 821 "\tinodes in use: %s limits (soft = %s hard = %s "
822 "grace = %s", scuri, ssoft, shard, stime); 822 "grace = %s", scuri, ssoft, shard, stime);
823 if (cnt == 3) { 823 if (cnt == 3) {
824 if (version != 1 || 824 if (version != 1 ||
825 last_char(scuri) != ',' || 825 last_char(scuri) != ',' ||
826 last_char(ssoft) != ',' || 826 last_char(ssoft) != ',' ||
827 last_char(shard) != ')') { 827 last_char(shard) != ')') {
828 warnx("%s:%s: bad format %d", 828 warnx("%s:%s: bad format %d",
829 fsp, line2, cnt); 829 fsp, line2, cnt);
830 goto out; 830 goto out;
831 } 831 }
832 stime[0] = '\0'; 832 stime[0] = '\0';
833 } else if (cnt == 4) { 833 } else if (cnt == 4) {
834 if (version < 2 || 834 if (version < 2 ||
835 last_char(scuri) != ',' || 835 last_char(scuri) != ',' ||
836 last_char(ssoft) != ',' || 836 last_char(ssoft) != ',' ||
837 last_char(shard) != ',' || 837 last_char(shard) != ',' ||
838 last_char(stime) != ')') { 838 last_char(stime) != ')') {
839 warnx("%s:%s: bad format %d", 839 warnx("%s:%s: bad format %d",
840 fsp, line2, cnt); 840 fsp, line2, cnt);
841 goto out; 841 goto out;
842 } 842 }
843 } else { 843 } else {
844 warnx("%s: %s: bad format", fsp, line2); 844 warnx("%s: %s: bad format", fsp, line2);
845 goto out; 845 goto out;
846 } 846 }
847 /* drop last char which is ',' or ')' */ 847 /* drop last char which is ',' or ')' */
848 last_char(scuri) = '\0'; 848 last_char(scuri) = '\0';
849 last_char(ssoft) = '\0'; 849 last_char(ssoft) = '\0';
850 last_char(shard) = '\0'; 850 last_char(shard) = '\0';
851 last_char(stime) = '\0'; 851 last_char(stime) = '\0';
852 if (intrd(ssoft, &softi, 0) != 0) { 852 if (intrd(ssoft, &softi, 0) != 0) {
853 warnx("%s:%s: bad number", fsp, ssoft); 853 warnx("%s:%s: bad number", fsp, ssoft);
854 goto out; 854 goto out;
855 } 855 }
856 if (intrd(shard, &hardi, 0) != 0) { 856 if (intrd(shard, &hardi, 0) != 0) {
857 warnx("%s:%s: bad number", fsp, shard); 857 warnx("%s:%s: bad number", fsp, shard);
858 goto out; 858 goto out;
859 } 859 }
860 if (cnt == 4) { 860 if (cnt == 4) {
861 if (timeprd(stime, &gracei) != 0) { 861 if (timeprd(stime, &gracei) != 0) {
862 warnx("%s:%s: bad number", fsp, stime); 862 warnx("%s:%s: bad number", fsp, stime);
863 goto out; 863 goto out;
864 } 864 }
865 } 865 }
866 } 866 }
867 for (qup = qlist->head; qup; qup = qup->next) { 867 for (qup = qlist->head; qup; qup = qup->next) {
868 struct quotaval *q = qup->qv; 868 struct quotaval *q = qup->qv;
869 char b1[32], b2[32]; 869 char b1[32], b2[32];
870 if (strcmp(fsp, qup->fsname)) 870 if (strcmp(fsp, qup->fsname))
871 continue; 871 continue;
872 if (version == 1 && dflag) { 872 if (version == 1 && dflag) {
873 q[QL_BLK].qv_grace = graceb; 873 q[QL_BLK].qv_grace = graceb;
874 q[QL_FL].qv_grace = gracei; 874 q[QL_FL].qv_grace = gracei;
875 qup->flags |= FOUND; 875 qup->flags |= FOUND;
876 continue; 876 continue;
877 } 877 }
878 878
879 if (strcmp(intprt(b1, 21, q[QL_BLK].qv_usage, 879 if (strcmp(intprt(b1, 21, q[QL_BLK].qv_usage,
880 HN_NOSPACE | HN_B, Hflag), 880 HN_NOSPACE | HN_B, Hflag),
881 scurb) != 0 || 881 scurb) != 0 ||
882 strcmp(intprt(b2, 21, q[QL_FL].qv_usage, 882 strcmp(intprt(b2, 21, q[QL_FL].qv_usage,
883 HN_NOSPACE, Hflag), 883 HN_NOSPACE, Hflag),
884 scuri) != 0) { 884 scuri) != 0) {
885 warnx("%s: cannot change current allocation", 885 warnx("%s: cannot change current allocation",
886 fsp); 886 fsp);
887 break; 887 break;
888 } 888 }
889 /* 889 /*
890 * Cause time limit to be reset when the quota 890 * Cause time limit to be reset when the quota
891 * is next used if previously had no soft limit 891 * is next used if previously had no soft limit
892 * or were under it, but now have a soft limit 892 * or were under it, but now have a soft limit
893 * and are over it. 893 * and are over it.
894 */ 894 */
895 if (q[QL_BLK].qv_usage && 895 if (q[QL_BLK].qv_usage &&
896 q[QL_BLK].qv_usage >= softb && 896 q[QL_BLK].qv_usage >= softb &&
897 (q[QL_BLK].qv_softlimit == 0 || 897 (q[QL_BLK].qv_softlimit == 0 ||
898 q[QL_BLK].qv_usage < q[QL_BLK].qv_softlimit)) 898 q[QL_BLK].qv_usage < q[QL_BLK].qv_softlimit))
899 q[QL_BLK].qv_expiretime = 0; 899 q[QL_BLK].qv_expiretime = 0;
900 if (q[QL_FL].qv_usage && 900 if (q[QL_FL].qv_usage &&
901 q[QL_FL].qv_usage >= softi && 901 q[QL_FL].qv_usage >= softi &&
902 (q[QL_FL].qv_softlimit == 0 || 902 (q[QL_FL].qv_softlimit == 0 ||
903 q[QL_FL].qv_usage < q[QL_FL].qv_softlimit)) 903 q[QL_FL].qv_usage < q[QL_FL].qv_softlimit))
904 q[QL_FL].qv_expiretime = 0; 904 q[QL_FL].qv_expiretime = 0;
905 q[QL_BLK].qv_softlimit = softb; 905 q[QL_BLK].qv_softlimit = softb;
906 q[QL_BLK].qv_hardlimit = hardb; 906 q[QL_BLK].qv_hardlimit = hardb;
907 if (version == 2) 907 if (version == 2)
908 q[QL_BLK].qv_grace = graceb; 908 q[QL_BLK].qv_grace = graceb;
909 q[QL_FL].qv_softlimit = softi; 909 q[QL_FL].qv_softlimit = softi;
910 q[QL_FL].qv_hardlimit = hardi; 910 q[QL_FL].qv_hardlimit = hardi;
911 if (version == 2) 911 if (version == 2)
912 q[QL_FL].qv_grace = gracei; 912 q[QL_FL].qv_grace = gracei;
913 qup->flags |= FOUND; 913 qup->flags |= FOUND;
914 } 914 }
915 } 915 }
916out: 916out:
917 fclose(fd); 917 fclose(fd);
918 /* 918 /*
919 * Disable quotas for any filesystems that have not been found. 919 * Disable quotas for any filesystems that have not been found.
920 */ 920 */
921 for (qup = qlist->head; qup; qup = qup->next) { 921 for (qup = qlist->head; qup; qup = qup->next) {
922 struct quotaval *q = qup->qv; 922 struct quotaval *q = qup->qv;
923 if (qup->flags & FOUND) { 923 if (qup->flags & FOUND) {
924 qup->flags &= ~FOUND; 924 qup->flags &= ~FOUND;
925 continue; 925 continue;
926 } 926 }
927 q[QL_BLK].qv_softlimit = UQUAD_MAX; 927 q[QL_BLK].qv_softlimit = UQUAD_MAX;
928 q[QL_BLK].qv_hardlimit = UQUAD_MAX; 928 q[QL_BLK].qv_hardlimit = UQUAD_MAX;
929 q[QL_BLK].qv_grace = 0; 929 q[QL_BLK].qv_grace = 0;
930 q[QL_FL].qv_softlimit = UQUAD_MAX; 930 q[QL_FL].qv_softlimit = UQUAD_MAX;
931 q[QL_FL].qv_hardlimit = UQUAD_MAX; 931 q[QL_FL].qv_hardlimit = UQUAD_MAX;
932 q[QL_FL].qv_grace = 0; 932 q[QL_FL].qv_grace = 0;
933 } 933 }
934 return 1; 934 return 1;
935} 935}
936 936
937//////////////////////////////////////////////////////////// 937////////////////////////////////////////////////////////////
938// actions 938// actions
939 939
940static void 940static void
941replicate(const char *fs, int idtype, const char *protoname, 941replicate(const char *fs, int idtype, const char *protoname,
942 char **names, int numnames) 942 char **names, int numnames)
943{ 943{
944 long protoid, id; 944 long protoid, id;
945 struct quotalist *protoprivs; 945 struct quotalist *protoprivs;
946 struct quotause *qup; 946 struct quotause *qup;
947 int i; 947 int i;
948 948
949 if ((protoid = getidbyname(protoname, idtype)) == -1) 949 if ((protoid = getidbyname(protoname, idtype)) == -1)
950 exit(1); 950 exit(1);
951 protoprivs = getprivs(protoid, 0, idtype, fs); 951 protoprivs = getprivs(protoid, 0, idtype, fs);
952 for (qup = protoprivs->head; qup; qup = qup->next) { 952 for (qup = protoprivs->head; qup; qup = qup->next) {
953 qup->qv[QL_BLK].qv_expiretime = 0; 953 qup->qv[QL_BLK].qv_expiretime = 0;
954 qup->qv[QL_FL].qv_expiretime = 0; 954 qup->qv[QL_FL].qv_expiretime = 0;
955 } 955 }
956 for (i=0; i<numnames; i++) { 956 for (i=0; i<numnames; i++) {
957 id = getidbyname(names[i], idtype); 957 id = getidbyname(names[i], idtype);
958 if (id == -1) 958 if (id == -1)
959 continue; 959 continue;
960 putprivs(id, idtype, protoprivs); 960 putprivs(id, idtype, protoprivs);
961 } 961 }
962 /* XXX */ 962 /* XXX */
963 /* quotalist_destroy(protoprivs); */ 963 /* quotalist_destroy(protoprivs); */
964} 964}
965 965
966static void 966static void
967assign(const char *fs, int idtype, 967assign(const char *fs, int idtype,
968 char *soft, char *hard, char *grace, 968 char *soft, char *hard, char *grace,
969 char **names, int numnames) 969 char **names, int numnames)
970{ 970{
971 struct quotalist *curprivs; 971 struct quotalist *curprivs;
972 struct quotause *lqup; 972 struct quotause *lqup;
973 u_int64_t softb, hardb, softi, hardi; 973 u_int64_t softb, hardb, softi, hardi;
974 time_t graceb, gracei; 974 time_t graceb, gracei;
975 char *str; 975 char *str;
976 long id; 976 long id;
977 int dflag; 977 int dflag;
978 int i; 978 int i;
979 979
980 if (soft) { 980 if (soft) {
981 str = strsep(&soft, "/"); 981 str = strsep(&soft, "/");
982 if (str[0] == '\0' || soft == NULL || soft[0] == '\0') 982 if (str[0] == '\0' || soft == NULL || soft[0] == '\0')
983 usage(); 983 usage();
984 984
985 if (intrd(str, &softb, HN_B) != 0) 985 if (intrd(str, &softb, HN_B) != 0)
986 errx(1, "%s: bad number", str); 986 errx(1, "%s: bad number", str);
987 if (intrd(soft, &softi, 0) != 0) 987 if (intrd(soft, &softi, 0) != 0)
988 errx(1, "%s: bad number", soft); 988 errx(1, "%s: bad number", soft);
989 } 989 }
990 if (hard) { 990 if (hard) {
991 str = strsep(&hard, "/"); 991 str = strsep(&hard, "/");
992 if (str[0] == '\0' || hard == NULL || hard[0] == '\0') 992 if (str[0] == '\0' || hard == NULL || hard[0] == '\0')
993 usage(); 993 usage();
994 994
995 if (intrd(str, &hardb, HN_B) != 0) 995 if (intrd(str, &hardb, HN_B) != 0)
996 errx(1, "%s: bad number", str); 996 errx(1, "%s: bad number", str);
997 if (intrd(hard, &hardi, 0) != 0) 997 if (intrd(hard, &hardi, 0) != 0)
998 errx(1, "%s: bad number", hard); 998 errx(1, "%s: bad number", hard);
999 } 999 }
1000 if (grace) { 1000 if (grace) {
1001 str = strsep(&grace, "/"); 1001 str = strsep(&grace, "/");
1002 if (str[0] == '\0' || grace == NULL || grace[0] == '\0') 1002 if (str[0] == '\0' || grace == NULL || grace[0] == '\0')
1003 usage(); 1003 usage();
1004 1004
1005 if (timeprd(str, &graceb) != 0) 1005 if (timeprd(str, &graceb) != 0)
1006 errx(1, "%s: bad number", str); 1006 errx(1, "%s: bad number", str);
1007 if (timeprd(grace, &gracei) != 0) 1007 if (timeprd(grace, &gracei) != 0)
1008 errx(1, "%s: bad number", grace); 1008 errx(1, "%s: bad number", grace);
1009 } 1009 }
1010 for (i=0; i<numnames; i++) { 1010 for (i=0; i<numnames; i++) {
1011 if (names[i] == NULL) { 1011 if (names[i] == NULL) {
1012 id = 0; 1012 id = 0;
1013 dflag = 1; 1013 dflag = 1;
1014 } else { 1014 } else {
1015 id = getidbyname(names[i], idtype); 1015 id = getidbyname(names[i], idtype);
1016 if (id == -1) 1016 if (id == -1)
1017 continue; 1017 continue;
1018 dflag = 0; 1018 dflag = 0;
1019 } 1019 }
1020 1020
1021 curprivs = getprivs(id, dflag, idtype, fs); 1021 curprivs = getprivs(id, dflag, idtype, fs);
1022 for (lqup = curprivs->head; lqup; lqup = lqup->next) { 1022 for (lqup = curprivs->head; lqup; lqup = lqup->next) {
1023 struct quotaval *q = lqup->qv; 1023 struct quotaval *q = lqup->qv;
1024 if (soft) { 1024 if (soft) {
1025 if (!dflag && softb && 1025 if (!dflag && softb &&
1026 q[QL_BLK].qv_usage >= softb && 1026 q[QL_BLK].qv_usage >= softb &&
1027 (q[QL_BLK].qv_softlimit == 0 || 1027 (q[QL_BLK].qv_softlimit == 0 ||
1028 q[QL_BLK].qv_usage < 1028 q[QL_BLK].qv_usage <
1029 q[QL_BLK].qv_softlimit)) 1029 q[QL_BLK].qv_softlimit))
1030 q[QL_BLK].qv_expiretime = 0; 1030 q[QL_BLK].qv_expiretime = 0;
1031 if (!dflag && softi && 1031 if (!dflag && softi &&
1032 q[QL_FL].qv_usage >= softb && 1032 q[QL_FL].qv_usage >= softb &&
1033 (q[QL_FL].qv_softlimit == 0 || 1033 (q[QL_FL].qv_softlimit == 0 ||
1034 q[QL_FL].qv_usage < 1034 q[QL_FL].qv_usage <
1035 q[QL_FL].qv_softlimit)) 1035 q[QL_FL].qv_softlimit))
1036 q[QL_FL].qv_expiretime = 0; 1036 q[QL_FL].qv_expiretime = 0;
1037 q[QL_BLK].qv_softlimit = softb; 1037 q[QL_BLK].qv_softlimit = softb;
1038 q[QL_FL].qv_softlimit = softi; 1038 q[QL_FL].qv_softlimit = softi;
1039 } 1039 }
1040 if (hard) { 1040 if (hard) {
1041 q[QL_BLK].qv_hardlimit = hardb; 1041 q[QL_BLK].qv_hardlimit = hardb;
1042 q[QL_FL].qv_hardlimit = hardi; 1042 q[QL_FL].qv_hardlimit = hardi;
1043 } 1043 }
1044 if (grace) { 1044 if (grace) {
1045 q[QL_BLK].qv_grace = graceb; 1045 q[QL_BLK].qv_grace = graceb;
1046 q[QL_FL].qv_grace = gracei; 1046 q[QL_FL].qv_grace = gracei;
1047 } 1047 }
1048 } 1048 }
1049 putprivs(id, idtype, curprivs); 1049 putprivs(id, idtype, curprivs);
1050 quotalist_destroy(curprivs); 1050 quotalist_destroy(curprivs);
1051 } 1051 }
1052} 1052}
1053 1053
1054static void 1054static void
1055clear(const char *fs, int idtype, char **names, int numnames) 1055clear(const char *fs, int idtype, char **names, int numnames)
1056{ 1056{
1057 clearpriv(numnames, names, fs, idtype); 1057 clearpriv(numnames, names, fs, idtype);
1058} 1058}
1059 1059
1060static void 1060static void
1061editone(const char *fs, int idtype, const char *name, 1061editone(const char *fs, int idtype, const char *name,
1062 int tmpfd, const char *tmppath) 1062 int tmpfd, const char *tmppath)
1063{ 1063{
1064 struct quotalist *curprivs; 1064 struct quotalist *curprivs;
1065 long id; 1065 long id;
1066 int dflag; 1066 int dflag;
1067 1067
1068 if (name == NULL) { 1068 if (name == NULL) {
1069 id = 0; 1069 id = 0;
1070 dflag = 1; 1070 dflag = 1;
1071 } else { 1071 } else {
1072 id = getidbyname(name, idtype); 1072 id = getidbyname(name, idtype);
1073 if (id == -1) 1073 if (id == -1)
1074 return; 1074 return;
1075 dflag = 0; 1075 dflag = 0;
1076 } 1076 }
1077 curprivs = getprivs(id, dflag, idtype, fs); 1077 curprivs = getprivs(id, dflag, idtype, fs);
1078 1078
1079 if (writeprivs(curprivs, tmpfd, name, idtype) == 0) 1079 if (writeprivs(curprivs, tmpfd, name, idtype) == 0)
1080 goto fail; 1080 goto fail;
1081 1081
1082 if (editit(tmppath) == 0) 1082 if (editit(tmppath) == 0)
1083 goto fail; 1083 goto fail;
1084 1084
1085 if (readprivs(curprivs, tmpfd, dflag) == 0) 1085 if (readprivs(curprivs, tmpfd, dflag) == 0)
1086 goto fail; 1086 goto fail;
1087 1087
1088 putprivs(id, idtype, curprivs); 1088 putprivs(id, idtype, curprivs);
1089fail: 1089fail:
1090 quotalist_destroy(curprivs); 1090 quotalist_destroy(curprivs);
1091} 1091}
1092 1092
1093static void 1093static void
1094edit(const char *fs, int idtype, char **names, int numnames) 1094edit(const char *fs, int idtype, char **names, int numnames)
1095{ 1095{
1096 char tmppath[] = _PATH_TMPFILE; 1096 char tmppath[] = _PATH_TMPFILE;
1097 int tmpfd, i; 1097 int tmpfd, i;
1098 1098
1099 tmpfd = mkstemp(tmppath); 1099 tmpfd = mkstemp(tmppath);
1100 fchown(tmpfd, getuid(), getgid()); 1100 fchown(tmpfd, getuid(), getgid());
1101 1101
1102 for (i=0; i<numnames; i++) { 1102 for (i=0; i<numnames; i++) {
1103 editone(fs, idtype, names[i], tmpfd, tmppath); 1103 editone(fs, idtype, names[i], tmpfd, tmppath);
1104 } 1104 }
1105 1105
1106 close(tmpfd); 1106 close(tmpfd);
1107 unlink(tmppath); 1107 unlink(tmppath);
1108} 1108}
1109 1109
1110//////////////////////////////////////////////////////////// 1110////////////////////////////////////////////////////////////
1111// main 1111// main
1112 1112
1113static void 1113static void
1114usage(void) 1114usage(void)
1115{ 1115{
1116 const char *p = getprogname(); 1116 const char *p = getprogname();
1117 fprintf(stderr, 1117 fprintf(stderr,
1118 "Usage: %s [-D] [-H] [-u] [-p <username>] [-f <filesystem>] " 1118 "Usage: %s [-D] [-H] [-u] [-p <username>] [-f <filesystem>] "
1119 "-d | <username> ...\n" 1119 "-d | <username> ...\n"
1120 "\t%s [-D] [-H] -g [-p <groupname>] [-f <filesystem>] " 1120 "\t%s [-D] [-H] -g [-p <groupname>] [-f <filesystem>] "
1121 "-d | <groupname> ...\n" 1121 "-d | <groupname> ...\n"
1122 "\t%s [-D] [-u] [-f <filesystem>] [-s b#/i#] [-h b#/i#] [-t t#/t#] " 1122 "\t%s [-D] [-u] [-f <filesystem>] [-s b#/i#] [-h b#/i#] [-t t#/t#] "
1123 "-d | <username> ...\n" 1123 "-d | <username> ...\n"
1124 "\t%s [-D] -g [-f <filesystem>] [-s b#/i#] [-h b#/i#] [-t t#/t#] " 1124 "\t%s [-D] -g [-f <filesystem>] [-s b#/i#] [-h b#/i#] [-t t#/t#] "
1125 "-d | <groupname> ...\n" 1125 "-d | <groupname> ...\n"
1126 "\t%s [-D] [-H] [-u] -c [-f <filesystem>] username ...\n" 1126 "\t%s [-D] [-H] [-u] -c [-f <filesystem>] username ...\n"
1127 "\t%s [-D] [-H] -g -c [-f <filesystem>] groupname ...\n", 1127 "\t%s [-D] [-H] -g -c [-f <filesystem>] groupname ...\n",
1128 p, p, p, p, p, p); 1128 p, p, p, p, p, p);
1129 exit(1); 1129 exit(1);
1130} 1130}
1131 1131
1132int 1132int
1133main(int argc, char *argv[]) 1133main(int argc, char *argv[])
1134{ 1134{
1135 int idtype; 1135 int idtype;
1136 char *protoname; 1136 char *protoname;
1137 char *soft = NULL, *hard = NULL, *grace = NULL; 1137 char *soft = NULL, *hard = NULL, *grace = NULL;
1138 char *fs = NULL; 1138 char *fs = NULL;
1139 int ch; 1139 int ch;
1140 int pflag = 0; 1140 int pflag = 0;
1141 int cflag = 0; 1141 int cflag = 0;
1142 int dflag = 0; 1142 int dflag = 0;
1143 1143
1144 if (argc < 2) 1144 if (argc < 2)
1145 usage(); 1145 usage();
1146 if (getuid()) 1146 if (getuid())
1147 errx(1, "permission denied"); 1147 errx(1, "permission denied");
1148 protoname = NULL; 1148 protoname = NULL;
1149 idtype = QUOTA_IDTYPE_USER; 1149 idtype = QUOTA_IDTYPE_USER;
1150 while ((ch = getopt(argc, argv, "DHcdugp:s:h:t:f:")) != -1) { 1150 while ((ch = getopt(argc, argv, "DHcdugp:s:h:t:f:")) != -1) {
1151 switch(ch) { 1151 switch(ch) {
1152 case 'D': 1152 case 'D':
1153 Dflag++; 1153 Dflag++;
1154 break; 1154 break;
1155 case 'H': 1155 case 'H':
1156 Hflag++; 1156 Hflag++;
1157 break; 1157 break;
1158 case 'c': 1158 case 'c':
1159 cflag++; 1159 cflag++;
1160 break; 1160 break;
1161 case 'd': 1161 case 'd':
1162 dflag++; 1162 dflag++;
1163 break; 1163 break;
1164 case 'p': 1164 case 'p':
1165 protoname = optarg; 1165 protoname = optarg;
1166 pflag++; 1166 pflag++;
1167 break; 1167 break;
1168 case 'g': 1168 case 'g':
1169 idtype = QUOTA_IDTYPE_GROUP; 1169 idtype = QUOTA_IDTYPE_GROUP;
1170 break; 1170 break;
1171 case 'u': 1171 case 'u':
1172 idtype = QUOTA_IDTYPE_USER; 1172 idtype = QUOTA_IDTYPE_USER;
1173 break; 1173 break;
1174 case 's': 1174 case 's':
1175 soft = optarg; 1175 soft = optarg;
1176 break; 1176 break;
1177 case 'h': 1177 case 'h':
1178 hard = optarg; 1178 hard = optarg;
1179 break; 1179 break;
1180 case 't': 1180 case 't':
1181 grace = optarg; 1181 grace = optarg;
1182 break; 1182 break;
1183 case 'f': 1183 case 'f':
1184 fs = optarg; 1184 fs = optarg;
1185 break; 1185 break;
1186 default: 1186 default:
1187 usage(); 1187 usage();
1188 } 1188 }
1189 } 1189 }
1190 argc -= optind; 1190 argc -= optind;
1191 argv += optind; 1191 argv += optind;
1192 1192
1193 if (pflag) { 1193 if (pflag) {
1194 if (soft || hard || grace || dflag || cflag) 1194 if (soft || hard || grace || dflag || cflag)
1195 usage(); 1195 usage();
1196 replicate(fs, idtype, protoname, argv, argc); 1196 replicate(fs, idtype, protoname, argv, argc);
1197 } else if (soft || hard || grace) { 1197 } else if (soft || hard || grace) {
1198 if (cflag) 1198 if (cflag)
1199 usage(); 1199 usage();
1200 if (dflag) { 1200 if (dflag) {
1201 /* use argv[argc], which is null, to mean 'default' */ 1201 /* use argv[argc], which is null, to mean 'default' */
1202 argc++; 1202 argc++;
1203 } 1203 }
1204 assign(fs, idtype, soft, hard, grace, argv, argc); 1204 assign(fs, idtype, soft, hard, grace, argv, argc);
1205 } else if (cflag) { 1205 } else if (cflag) {
1206 if (dflag) 1206 if (dflag)
1207 usage(); 1207 usage();
1208 clear(fs, idtype, argv, argc); 1208 clear(fs, idtype, argv, argc);
1209 } else { 1209 } else {
1210 if (dflag) { 1210 if (dflag) {
1211 /* use argv[argc], which is null, to mean 'default' */ 1211 /* use argv[argc], which is null, to mean 'default' */
1212 argc++; 1212 argc++;
1213 } 1213 }
1214 edit(fs, idtype, argv, argc); 1214 edit(fs, idtype, argv, argc);
1215 } 1215 }
1216 return 0; 1216 return 0;
1217} 1217}