Implement "get version" quotactl command, which return the filesystem's enabled quota versiob (1 for legacy, 2 for new). For quota2, make quota and repquota print the user's allowed grace period if -v is given and not overquota (if overquota, the remaining time is printed instead, as usual).diff -r1.68.4.4 -r1.68.4.5 src/sys/ufs/ufs/ufs_quota.c
(bouyer)
--- src/sys/ufs/ufs/ufs_quota.c 2011/01/30 00:25:19 1.68.4.4
+++ src/sys/ufs/ufs/ufs_quota.c 2011/01/30 19:38:46 1.68.4.5
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: ufs_quota.c,v 1.68.4.4 2011/01/30 00:25:19 bouyer Exp $ */ | 1 | /* $NetBSD: ufs_quota.c,v 1.68.4.5 2011/01/30 19:38:46 bouyer Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1982, 1986, 1990, 1993, 1995 | 4 | * Copyright (c) 1982, 1986, 1990, 1993, 1995 | |
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. | |
@@ -25,51 +25,53 @@ | @@ -25,51 +25,53 @@ | |||
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 | * @(#)ufs_quota.c 8.5 (Berkeley) 5/20/95 | 34 | * @(#)ufs_quota.c 8.5 (Berkeley) 5/20/95 | |
35 | */ | 35 | */ | |
36 | 36 | |||
37 | #include <sys/cdefs.h> | 37 | #include <sys/cdefs.h> | |
38 | __KERNEL_RCSID(0, "$NetBSD: ufs_quota.c,v 1.68.4.4 2011/01/30 00:25:19 bouyer Exp $"); | 38 | __KERNEL_RCSID(0, "$NetBSD: ufs_quota.c,v 1.68.4.5 2011/01/30 19:38:46 bouyer Exp $"); | |
39 | 39 | |||
40 | #if defined(_KERNEL_OPT) | 40 | #if defined(_KERNEL_OPT) | |
41 | #include "opt_quota.h" | 41 | #include "opt_quota.h" | |
42 | #endif | 42 | #endif | |
43 | #include <sys/param.h> | 43 | #include <sys/param.h> | |
44 | #include <sys/kernel.h> | 44 | #include <sys/kernel.h> | |
45 | #include <sys/systm.h> | 45 | #include <sys/systm.h> | |
46 | #include <sys/namei.h> | 46 | #include <sys/namei.h> | |
47 | #include <sys/file.h> | 47 | #include <sys/file.h> | |
48 | #include <sys/proc.h> | 48 | #include <sys/proc.h> | |
49 | #include <sys/vnode.h> | 49 | #include <sys/vnode.h> | |
50 | #include <sys/mount.h> | 50 | #include <sys/mount.h> | |
51 | #include <sys/kauth.h> | 51 | #include <sys/kauth.h> | |
52 | 52 | |||
53 | #include <ufs/ufs/quota.h> | 53 | #include <ufs/ufs/quota.h> | |
54 | #include <ufs/ufs/inode.h> | 54 | #include <ufs/ufs/inode.h> | |
55 | #include <ufs/ufs/ufsmount.h> | 55 | #include <ufs/ufs/ufsmount.h> | |
56 | #include <ufs/ufs/ufs_extern.h> | 56 | #include <ufs/ufs/ufs_extern.h> | |
57 | #include <ufs/ufs/ufs_quota.h> | 57 | #include <ufs/ufs/ufs_quota.h> | |
58 | #include <ufs/ufs/quota2_prop.h> | 58 | #include <ufs/ufs/quota2_prop.h> | |
59 | 59 | |||
60 | kmutex_t dqlock; | 60 | kmutex_t dqlock; | |
61 | kcondvar_t dqcv; | 61 | kcondvar_t dqcv; | |
62 | 62 | |||
63 | static int quota_handle_cmd_get_version(struct mount *, struct lwp *, | |||
64 | prop_dictionary_t, prop_array_t); | |||
63 | static int quota_handle_cmd_get(struct mount *, struct lwp *, | 65 | static int quota_handle_cmd_get(struct mount *, struct lwp *, | |
64 | prop_dictionary_t, int, prop_array_t); | 66 | prop_dictionary_t, int, prop_array_t); | |
65 | static int quota_handle_cmd_set(struct mount *, struct lwp *, | 67 | static int quota_handle_cmd_set(struct mount *, struct lwp *, | |
66 | prop_dictionary_t, int, prop_array_t); | 68 | prop_dictionary_t, int, prop_array_t); | |
67 | static int quota_handle_cmd_getall(struct mount *, struct lwp *, | 69 | static int quota_handle_cmd_getall(struct mount *, struct lwp *, | |
68 | prop_dictionary_t, int, prop_array_t); | 70 | prop_dictionary_t, int, prop_array_t); | |
69 | /* | 71 | /* | |
70 | * Initialize the quota fields of an inode. | 72 | * Initialize the quota fields of an inode. | |
71 | */ | 73 | */ | |
72 | void | 74 | void | |
73 | ufsquota_init(struct inode *ip) | 75 | ufsquota_init(struct inode *ip) | |
74 | { | 76 | { | |
75 | int i; | 77 | int i; | |
@@ -141,46 +143,96 @@ quota_handle_cmd(struct mount *mp, struc | @@ -141,46 +143,96 @@ quota_handle_cmd(struct mount *mp, struc | |||
141 | if (!strcmp(type, "user")) { | 143 | if (!strcmp(type, "user")) { | |
142 | q2type = USRQUOTA; | 144 | q2type = USRQUOTA; | |
143 | } else if (!strcmp(type, "group")) { | 145 | } else if (!strcmp(type, "group")) { | |
144 | q2type = GRPQUOTA; | 146 | q2type = GRPQUOTA; | |
145 | } else | 147 | } else | |
146 | return EOPNOTSUPP; | 148 | return EOPNOTSUPP; | |
147 | datas = prop_dictionary_get(cmddict, "data"); | 149 | datas = prop_dictionary_get(cmddict, "data"); | |
148 | if (datas == NULL || prop_object_type(datas) != PROP_TYPE_ARRAY) | 150 | if (datas == NULL || prop_object_type(datas) != PROP_TYPE_ARRAY) | |
149 | return EINVAL; | 151 | return EINVAL; | |
150 | 152 | |||
151 | prop_object_retain(datas); | 153 | prop_object_retain(datas); | |
152 | prop_dictionary_remove(cmddict, "data"); /* prepare for return */ | 154 | prop_dictionary_remove(cmddict, "data"); /* prepare for return */ | |
153 | 155 | |||
156 | if (strcmp(cmd, "get version") == 0) { | |||
157 | error = quota_handle_cmd_get_version(mp, l, cmddict, datas); | |||
158 | goto end; | |||
159 | } | |||
154 | if (strcmp(cmd, "get") == 0) { | 160 | if (strcmp(cmd, "get") == 0) { | |
155 | error = quota_handle_cmd_get(mp, l, cmddict, q2type, datas); | 161 | error = quota_handle_cmd_get(mp, l, cmddict, q2type, datas); | |
156 | goto end; | 162 | goto end; | |
157 | } | 163 | } | |
158 | if (strcmp(cmd, "set") == 0) { | 164 | if (strcmp(cmd, "set") == 0) { | |
159 | error = quota_handle_cmd_set(mp, l, cmddict, q2type, datas); | 165 | error = quota_handle_cmd_set(mp, l, cmddict, q2type, datas); | |
160 | goto end; | 166 | goto end; | |
161 | } | 167 | } | |
162 | if (strcmp(cmd, "getall") == 0) { | 168 | if (strcmp(cmd, "getall") == 0) { | |
163 | error = quota_handle_cmd_getall(mp, l, cmddict, q2type, datas); | 169 | error = quota_handle_cmd_getall(mp, l, cmddict, q2type, datas); | |
164 | goto end; | 170 | goto end; | |
165 | } | 171 | } | |
166 | error = EOPNOTSUPP; | 172 | error = EOPNOTSUPP; | |
167 | end: | 173 | end: | |
168 | error = (prop_dictionary_set_int8(cmddict, "return", | 174 | error = (prop_dictionary_set_int8(cmddict, "return", | |
169 | error) ? 0 : ENOMEM); | 175 | error) ? 0 : ENOMEM); | |
170 | prop_object_release(datas); | 176 | prop_object_release(datas); | |
171 | return error; | 177 | return error; | |
172 | } | 178 | } | |
173 | 179 | |||
180 | static int | |||
181 | quota_handle_cmd_get_version(struct mount *mp, struct lwp *l, | |||
182 | prop_dictionary_t cmddict, prop_array_t datas) | |||
183 | { | |||
184 | struct ufsmount *ump = VFSTOUFS(mp); | |||
185 | prop_array_t replies; | |||
186 | prop_dictionary_t data; | |||
187 | int error = 0; | |||
188 | ||||
189 | if ((ump->um_flags & (UFS_QUOTA|UFS_QUOTA2)) == 0) | |||
190 | return EOPNOTSUPP; | |||
191 | ||||
192 | replies = prop_array_create(); | |||
193 | if (replies == NULL) | |||
194 | return ENOMEM; | |||
195 | ||||
196 | data = prop_dictionary_create(); | |||
197 | if (data == NULL) { | |||
198 | prop_object_release(replies); | |||
199 | return ENOMEM; | |||
200 | } | |||
201 | ||||
202 | #ifdef QUOTA | |||
203 | if (ump->um_flags & UFS_QUOTA) { | |||
204 | if (!prop_dictionary_set_int8(data, "version", 1)) | |||
205 | error = ENOMEM; | |||
206 | } else | |||
207 | #endif | |||
208 | #ifdef QUOTA2 | |||
209 | if (ump->um_flags & UFS_QUOTA2) { | |||
210 | if (!prop_dictionary_set_int8(data, "version", 2)) | |||
211 | error = ENOMEM; | |||
212 | } else | |||
213 | #endif | |||
214 | error = 0; | |||
215 | if (error) | |||
216 | prop_object_release(data); | |||
217 | else if (!prop_array_add_and_rel(replies, data)) | |||
218 | error = ENOMEM; | |||
219 | if (error) | |||
220 | prop_object_release(replies); | |||
221 | else if (!prop_dictionary_set_and_rel(cmddict, "data", replies)) | |||
222 | error = ENOMEM; | |||
223 | return error; | |||
224 | } | |||
225 | ||||
174 | /* XXX shouldn't all this be in kauth ? */ | 226 | /* XXX shouldn't all this be in kauth ? */ | |
175 | static int | 227 | static int | |
176 | quota_get_auth(struct mount *mp, struct lwp *l, uid_t id) { | 228 | quota_get_auth(struct mount *mp, struct lwp *l, uid_t id) { | |
177 | /* The user can always query about his own quota. */ | 229 | /* The user can always query about his own quota. */ | |
178 | if (id == kauth_cred_getuid(l->l_cred)) | 230 | if (id == kauth_cred_getuid(l->l_cred)) | |
179 | return 0; | 231 | return 0; | |
180 | return kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_FS_QUOTA, | 232 | return kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_FS_QUOTA, | |
181 | KAUTH_REQ_SYSTEM_FS_QUOTA_GET, mp, KAUTH_ARG(id), NULL); | 233 | KAUTH_REQ_SYSTEM_FS_QUOTA_GET, mp, KAUTH_ARG(id), NULL); | |
182 | } | 234 | } | |
183 | 235 | |||
184 | static int | 236 | static int | |
185 | quota_handle_cmd_get(struct mount *mp, struct lwp *l, | 237 | quota_handle_cmd_get(struct mount *mp, struct lwp *l, | |
186 | prop_dictionary_t cmddict, int type, prop_array_t datas) | 238 | prop_dictionary_t cmddict, int type, prop_array_t datas) |
--- src/usr.bin/quota/Attic/getvfsquota.c 2011/01/28 22:15:36 1.1.2.1
+++ src/usr.bin/quota/Attic/getvfsquota.c 2011/01/30 19:38:45 1.1.2.2
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: getvfsquota.c,v 1.1.2.1 2011/01/28 22:15:36 bouyer Exp $ */ | 1 | /* $NetBSD: getvfsquota.c,v 1.1.2.2 2011/01/30 19:38:45 bouyer Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2011 Manuel Bouyer | 4 | * Copyright (c) 2011 Manuel Bouyer | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * This software is distributed under the following condiions | 6 | * This software is distributed under the following condiions | |
7 | * compliant with the NetBSD foundation policy. | 7 | * compliant with the NetBSD foundation policy. | |
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 | |
@@ -19,129 +19,152 @@ | @@ -19,129 +19,152 @@ | |||
19 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 19 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
20 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 20 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
21 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 21 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
22 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 22 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
28 | * POSSIBILITY OF SUCH DAMAGE. | 28 | * POSSIBILITY OF SUCH DAMAGE. | |
29 | */ | 29 | */ | |
30 | 30 | |||
31 | #include <sys/cdefs.h> | 31 | #include <sys/cdefs.h> | |
32 | __RCSID("$NetBSD: getvfsquota.c,v 1.1.2.1 2011/01/28 22:15:36 bouyer Exp $"); | 32 | __RCSID("$NetBSD: getvfsquota.c,v 1.1.2.2 2011/01/30 19:38:45 bouyer Exp $"); | |
33 | 33 | |||
34 | #include <stdio.h> | 34 | #include <stdio.h> | |
35 | #include <stdlib.h> | 35 | #include <stdlib.h> | |
36 | #include <errno.h> | 36 | #include <errno.h> | |
37 | #include <err.h> | 37 | #include <err.h> | |
38 | #include <string.h> | 38 | #include <string.h> | |
39 | 39 | |||
40 | #include <sys/types.h> | 40 | #include <sys/types.h> | |
41 | 41 | |||
42 | #include <ufs/ufs/quota2_prop.h> | 42 | #include <ufs/ufs/quota2_prop.h> | |
43 | #include <sys/quota.h> | 43 | #include <sys/quota.h> | |
44 | 44 | |||
45 | #include <getvfsquota.h> | 45 | #include <getvfsquota.h> | |
46 | 46 | |||
47 | const char *qfextension[] = INITQFNAMES; | 47 | const char *qfextension[] = INITQFNAMES; | |
48 | 48 | |||
49 | /* retrieve quotas from vfs, for the given user id */ | 49 | /* retrieve quotas from vfs, for the given user id */ | |
50 | int | 50 | int | |
51 | getvfsquota(const char *mp, struct quota2_entry *q2e, long id, int type, | 51 | getvfsquota(const char *mp, struct quota2_entry *q2e, int8_t *versp, | |
52 | int defaultq, int debug) | 52 | long id, int type, int defaultq, int debug) | |
53 | { | 53 | { | |
54 | prop_dictionary_t dict, data, cmd; | 54 | prop_dictionary_t dict, data, cmd; | |
55 | prop_array_t cmds, datas; | 55 | prop_array_t cmds, datas; | |
56 | prop_object_iterator_t iter; | |||
56 | struct plistref pref; | 57 | struct plistref pref; | |
57 | int error; | 58 | int error; | |
58 | int8_t error8; | 59 | int8_t error8; | |
59 | bool ret; | 60 | bool ret; | |
61 | int retval = 0; | |||
60 | 62 | |||
61 | dict = quota2_prop_create(); | 63 | dict = quota2_prop_create(); | |
62 | cmds = prop_array_create(); | 64 | cmds = prop_array_create(); | |
63 | datas = prop_array_create(); | 65 | datas = prop_array_create(); | |
64 | data = prop_dictionary_create(); | 66 | data = prop_dictionary_create(); | |
65 | 67 | |||
66 | if (dict == NULL || cmds == NULL || datas == NULL || data == NULL) | 68 | if (dict == NULL || cmds == NULL || datas == NULL || data == NULL) | |
67 | errx(1, "can't allocate proplist"); | 69 | errx(1, "can't allocate proplist"); | |
68 | 70 | |||
69 | if (defaultq) | 71 | if (defaultq) | |
70 | ret = prop_dictionary_set_cstring(data, "id", "default"); | 72 | ret = prop_dictionary_set_cstring(data, "id", "default"); | |
71 | else | 73 | else | |
72 | ret = prop_dictionary_set_uint32(data, "id", id); | 74 | ret = prop_dictionary_set_uint32(data, "id", id); | |
73 | if (!ret) | 75 | if (!ret) | |
74 | err(1, "prop_dictionary_set(id)"); | 76 | err(1, "prop_dictionary_set(id)"); | |
75 | 77 | |||
76 | if (!prop_array_add(datas, data)) | 78 | if (!prop_array_add(datas, data)) | |
77 | err(1, "prop_array_add(data)"); | 79 | err(1, "prop_array_add(data)"); | |
78 | prop_object_release(data); | 80 | prop_object_release(data); | |
79 | if (!quota2_prop_add_command(cmds, "get", qfextension[type], datas)) | 81 | if (!quota2_prop_add_command(cmds, "get", qfextension[type], datas)) | |
80 | err(1, "prop_add_command"); | 82 | err(1, "prop_add_command"); | |
83 | if (!quota2_prop_add_command(cmds, "get version", qfextension[type], | |||
84 | prop_array_create())) | |||
85 | err(1, "prop_add_command"); | |||
81 | if (!prop_dictionary_set(dict, "commands", cmds)) | 86 | if (!prop_dictionary_set(dict, "commands", cmds)) | |
82 | err(1, "prop_dictionary_set(command)"); | 87 | err(1, "prop_dictionary_set(command)"); | |
83 | if (debug) | 88 | if (debug) | |
84 | printf("message to kernel:\n%s\n", | 89 | printf("message to kernel:\n%s\n", | |
85 | prop_dictionary_externalize(dict)); | 90 | prop_dictionary_externalize(dict)); | |
86 | 91 | |||
87 | if (!prop_dictionary_send_syscall(dict, &pref)) | 92 | if (!prop_dictionary_send_syscall(dict, &pref)) | |
88 | err(1, "prop_dictionary_send_syscall"); | 93 | err(1, "prop_dictionary_send_syscall"); | |
89 | prop_object_release(dict); | 94 | prop_object_release(dict); | |
90 | 95 | |||
91 | if (quotactl(mp, &pref) != 0) | 96 | if (quotactl(mp, &pref) != 0) | |
92 | err(1, "quotactl"); | 97 | err(1, "quotactl"); | |
93 | 98 | |||
94 | if ((error = prop_dictionary_recv_syscall(&pref, &dict)) != 0) { | 99 | if ((error = prop_dictionary_recv_syscall(&pref, &dict)) != 0) { | |
95 | errx(1, "prop_dictionary_recv_syscall: %s\n", | 100 | errx(1, "prop_dictionary_recv_syscall: %s\n", | |
96 | strerror(error)); | 101 | strerror(error)); | |
97 | } | 102 | } | |
98 | if (debug) | 103 | if (debug) | |
99 | printf("reply from kernel:\n%s\n", | 104 | printf("reply from kernel:\n%s\n", | |
100 | prop_dictionary_externalize(dict)); | 105 | prop_dictionary_externalize(dict)); | |
101 | if ((error = quota2_get_cmds(dict, &cmds)) != 0) { | 106 | if ((error = quota2_get_cmds(dict, &cmds)) != 0) { | |
102 | errx(1, "quota2_get_cmds: %s\n", | 107 | errx(1, "quota2_get_cmds: %s\n", | |
103 | strerror(error)); | 108 | strerror(error)); | |
104 | } | 109 | } | |
105 | /* only one command, no need to iter */ | 110 | iter = prop_array_iterator(cmds); | |
106 | cmd = prop_array_get(cmds, 0); | 111 | if (iter == NULL) | |
107 | if (cmd == NULL) | 112 | err(1, "prop_array_iterator(cmds)"); | |
108 | err(1, "prop_array_get(cmd)"); | 113 | ||
109 | 114 | while ((cmd = prop_object_iterator_next(iter)) != NULL) { | ||
110 | if (!prop_dictionary_get_int8(cmd, "return", &error8)) | 115 | const char *cmdstr; | |
111 | err(1, "prop_get(return)"); | 116 | if (!prop_dictionary_get_cstring_nocopy(cmd, "command", | |
112 | 117 | &cmdstr)) | ||
113 | if (error8) { | 118 | err(1, "prop_get(command)"); | |
114 | if (error8 != ENOENT && error8 != ENODEV) { | 119 | if (!prop_dictionary_get_int8(cmd, "return", &error8)) | |
115 | if (defaultq) | 120 | err(1, "prop_get(return)"); | |
116 | fprintf(stderr, "get default %s quota: %s\n", | 121 | ||
117 | qfextension[type], strerror(error8)); | 122 | if (error8) { | |
118 | else | 123 | if (error8 != ENOENT && error8 != ENODEV) { | |
119 | fprintf(stderr, "get %s quota for %ld: %s\n", | 124 | if (defaultq) { | |
120 | qfextension[type], id, strerror(error8)); | 125 | fprintf(stderr, | |
126 | "get default %s quota: %s\n", | |||
127 | qfextension[type], | |||
128 | strerror(error8)); | |||
129 | } else { | |||
130 | fprintf(stderr, | |||
131 | "get %s quota for %ld: %s\n", | |||
132 | qfextension[type], id, | |||
133 | strerror(error8)); | |||
134 | } | |||
135 | } | |||
136 | prop_object_release(dict); | |||
137 | return (0); | |||
138 | } | |||
139 | datas = prop_dictionary_get(cmd, "data"); | |||
140 | if (datas == NULL) | |||
141 | err(1, "prop_dict_get(datas)"); | |||
142 | ||||
143 | if (strcmp("get version", cmdstr) == 0) { | |||
144 | data = prop_array_get(datas, 0); | |||
145 | if (data == NULL) | |||
146 | err(1, "prop_array_get(version)"); | |||
147 | if (!prop_dictionary_get_int8(data, "version", versp)) | |||
148 | err(1, "prop_get_int8(version)"); | |||
149 | continue; | |||
150 | } | |||
151 | if (strcmp("get", cmdstr) != 0) | |||
152 | err(1, "unknown command %s in reply", cmdstr); | |||
153 | ||||
154 | /* only one data, no need to iter */ | |||
155 | if (prop_array_count(datas) > 0) { | |||
156 | data = prop_array_get(datas, 0); | |||
157 | if (data == NULL) | |||
158 | err(1, "prop_array_get(data)"); | |||
159 | ||||
160 | error = quota2_dict_get_q2e_usage(data, q2e); | |||
161 | if (error) { | |||
162 | errx(1, "quota2_dict_get_q2e_usage: %s\n", | |||
163 | strerror(error)); | |||
164 | } | |||
165 | retval = 1; | |||
121 | } | 166 | } | |
122 | prop_object_release(dict); | |||
123 | return (0); | |||
124 | } | |||
125 | datas = prop_dictionary_get(cmd, "data"); | |||
126 | if (datas == NULL) | |||
127 | err(1, "prop_dict_get(datas)"); | |||
128 | ||||
129 | /* only one data, no need to iter */ | |||
130 | if (prop_array_count(datas) == 0) { | |||
131 | /* no quota for this user/group */ | |||
132 | prop_object_release(dict); | |||
133 | return (0); | |||
134 | } | |||
135 | ||||
136 | data = prop_array_get(datas, 0); | |||
137 | if (data == NULL) | |||
138 | err(1, "prop_array_get(data)"); | |||
139 | ||||
140 | error = quota2_dict_get_q2e_usage(data, q2e); | |||
141 | if (error) { | |||
142 | errx(1, "quota2_dict_get_q2e_usage: %s\n", | |||
143 | strerror(error)); | |||
144 | } | 167 | } | |
145 | prop_object_release(dict); | 168 | prop_object_release(dict); | |
146 | return (1); | 169 | return retval; | |
147 | } | 170 | } |
--- src/usr.bin/quota/Attic/getvfsquota.h 2011/01/28 22:15:36 1.1.2.1
+++ src/usr.bin/quota/Attic/getvfsquota.h 2011/01/30 19:38:45 1.1.2.2
@@ -1,5 +1,6 @@ | @@ -1,5 +1,6 @@ | |||
1 | /* $NetBSD: getvfsquota.h,v 1.1.2.1 2011/01/28 22:15:36 bouyer Exp $ */ | 1 | /* $NetBSD: getvfsquota.h,v 1.1.2.2 2011/01/30 19:38:45 bouyer Exp $ */ | |
2 | 2 | |||
3 | int getvfsquota(const char *, struct quota2_entry *, long, int, int, int); | 3 | int getvfsquota(const char *, struct quota2_entry *, int8_t *, | |
4 | long, int, int, int); | |||
4 | 5 | |||
5 | extern const char *qfextension[]; | 6 | extern const char *qfextension[]; |
--- src/usr.bin/quota/printquota.c 2011/01/30 00:21:08 1.1.2.3
+++ src/usr.bin/quota/printquota.c 2011/01/30 19:38:45 1.1.2.4
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: printquota.c,v 1.1.2.3 2011/01/30 00:21:08 bouyer Exp $ */ | 1 | /* $NetBSD: printquota.c,v 1.1.2.4 2011/01/30 19:38:45 bouyer Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1980, 1990, 1993 | 4 | * Copyright (c) 1980, 1990, 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. | |
@@ -32,27 +32,27 @@ | @@ -32,27 +32,27 @@ | |||
32 | * SUCH DAMAGE. | 32 | * SUCH DAMAGE. | |
33 | */ | 33 | */ | |
34 | 34 | |||
35 | #include <sys/cdefs.h> | 35 | #include <sys/cdefs.h> | |
36 | #ifndef lint | 36 | #ifndef lint | |
37 | __COPYRIGHT("@(#) Copyright (c) 1980, 1990, 1993\ | 37 | __COPYRIGHT("@(#) Copyright (c) 1980, 1990, 1993\ | |
38 | The Regents of the University of California. All rights reserved."); | 38 | The Regents of the University of California. All rights reserved."); | |
39 | #endif /* not lint */ | 39 | #endif /* not lint */ | |
40 | 40 | |||
41 | #ifndef lint | 41 | #ifndef lint | |
42 | #if 0 | 42 | #if 0 | |
43 | static char sccsid[] = "@(#)quota.c 8.4 (Berkeley) 4/28/95"; | 43 | static char sccsid[] = "@(#)quota.c 8.4 (Berkeley) 4/28/95"; | |
44 | #else | 44 | #else | |
45 | __RCSID("$NetBSD: printquota.c,v 1.1.2.3 2011/01/30 00:21:08 bouyer Exp $"); | 45 | __RCSID("$NetBSD: printquota.c,v 1.1.2.4 2011/01/30 19:38:45 bouyer Exp $"); | |
46 | #endif | 46 | #endif | |
47 | #endif /* not lint */ | 47 | #endif /* not lint */ | |
48 | 48 | |||
49 | #include <sys/param.h> | 49 | #include <sys/param.h> | |
50 | #include <sys/types.h> | 50 | #include <sys/types.h> | |
51 | 51 | |||
52 | #include <ctype.h> | 52 | #include <ctype.h> | |
53 | #include <stdio.h> | 53 | #include <stdio.h> | |
54 | #include <stdlib.h> | 54 | #include <stdlib.h> | |
55 | #include <string.h> | 55 | #include <string.h> | |
56 | #include <time.h> | 56 | #include <time.h> | |
57 | #include <unistd.h> | 57 | #include <unistd.h> | |
58 | #include <errno.h> | 58 | #include <errno.h> | |
@@ -90,34 +90,31 @@ intprt(uint64_t val, u_int flags, int hf | @@ -90,34 +90,31 @@ intprt(uint64_t val, u_int flags, int hf | |||
90 | } | 90 | } | |
91 | if (flags & HN_B) { | 91 | if (flags & HN_B) { | |
92 | /* traditionnal display: blocks are in kilobytes */ | 92 | /* traditionnal display: blocks are in kilobytes */ | |
93 | val = val / 1024; | 93 | val = val / 1024; | |
94 | } | 94 | } | |
95 | snprintf(buf, sizeof(buf), "%" PRIu64, val); | 95 | snprintf(buf, sizeof(buf), "%" PRIu64, val); | |
96 | return buf; | 96 | return buf; | |
97 | } | 97 | } | |
98 | 98 | |||
99 | /* | 99 | /* | |
100 | * Calculate the grace period and return a printable string for it. | 100 | * Calculate the grace period and return a printable string for it. | |
101 | */ | 101 | */ | |
102 | const char * | 102 | const char * | |
103 | timeprt(time_t seconds) | 103 | timeprt(time_t now, time_t seconds) | |
104 | { | 104 | { | |
105 | time_t hours, minutes; | 105 | time_t hours, minutes; | |
106 | static char buf[20]; | 106 | static char buf[20]; | |
107 | static time_t now; | |||
108 | 107 | |||
109 | if (now == 0) | |||
110 | time(&now); | |||
111 | if (now > seconds) | 108 | if (now > seconds) | |
112 | return ("none"); | 109 | return ("none"); | |
113 | seconds -= now; | 110 | seconds -= now; | |
114 | minutes = (seconds + 30) / 60; | 111 | minutes = (seconds + 30) / 60; | |
115 | hours = (minutes + 30) / 60; | 112 | hours = (minutes + 30) / 60; | |
116 | if (hours >= 36) { | 113 | if (hours >= 36) { | |
117 | (void)snprintf(buf, sizeof buf, "%ddays", | 114 | (void)snprintf(buf, sizeof buf, "%ddays", | |
118 | (int)((hours + 12) / 24)); | 115 | (int)((hours + 12) / 24)); | |
119 | return (buf); | 116 | return (buf); | |
120 | } | 117 | } | |
121 | if (minutes >= 60) { | 118 | if (minutes >= 60) { | |
122 | (void)snprintf(buf, sizeof buf, "%2d:%d", | 119 | (void)snprintf(buf, sizeof buf, "%2d:%d", | |
123 | (int)(minutes / 60), (int)(minutes % 60)); | 120 | (int)(minutes / 60), (int)(minutes % 60)); |
--- src/usr.bin/quota/printquota.h 2011/01/29 17:42:37 1.1.2.3
+++ src/usr.bin/quota/printquota.h 2011/01/30 19:38:45 1.1.2.4
@@ -1,7 +1,7 @@ | @@ -1,7 +1,7 @@ | |||
1 | /* $NetBSD: printquota.h,v 1.1.2.3 2011/01/29 17:42:37 bouyer Exp $ */ | 1 | /* $NetBSD: printquota.h,v 1.1.2.4 2011/01/30 19:38:45 bouyer Exp $ */ | |
2 | 2 | |||
3 | const char *intprt(uint64_t, u_int, int); | 3 | const char *intprt(uint64_t, u_int, int); | |
4 | #define HN_PRIV_UNLIMITED 0x80000000 /* print "unlimited" instead of "-" */ | 4 | #define HN_PRIV_UNLIMITED 0x80000000 /* print "unlimited" instead of "-" */ | |
5 | const char *timeprt(time_t); | 5 | const char *timeprt(time_t, time_t); | |
6 | int intrd(char *str, uint64_t *val, u_int); | 6 | int intrd(char *str, uint64_t *val, u_int); | |
7 | 7 |
--- src/usr.bin/quota/quota.c 2011/01/28 22:15:36 1.33.2.3
+++ src/usr.bin/quota/quota.c 2011/01/30 19:38:45 1.33.2.4
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: quota.c,v 1.33.2.3 2011/01/28 22:15:36 bouyer Exp $ */ | 1 | /* $NetBSD: quota.c,v 1.33.2.4 2011/01/30 19:38:45 bouyer Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1980, 1990, 1993 | 4 | * Copyright (c) 1980, 1990, 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. | |
@@ -32,27 +32,27 @@ | @@ -32,27 +32,27 @@ | |||
32 | * SUCH DAMAGE. | 32 | * SUCH DAMAGE. | |
33 | */ | 33 | */ | |
34 | 34 | |||
35 | #include <sys/cdefs.h> | 35 | #include <sys/cdefs.h> | |
36 | #ifndef lint | 36 | #ifndef lint | |
37 | __COPYRIGHT("@(#) Copyright (c) 1980, 1990, 1993\ | 37 | __COPYRIGHT("@(#) Copyright (c) 1980, 1990, 1993\ | |
38 | The Regents of the University of California. All rights reserved."); | 38 | The Regents of the University of California. All rights reserved."); | |
39 | #endif /* not lint */ | 39 | #endif /* not lint */ | |
40 | 40 | |||
41 | #ifndef lint | 41 | #ifndef lint | |
42 | #if 0 | 42 | #if 0 | |
43 | static char sccsid[] = "@(#)quota.c 8.4 (Berkeley) 4/28/95"; | 43 | static char sccsid[] = "@(#)quota.c 8.4 (Berkeley) 4/28/95"; | |
44 | #else | 44 | #else | |
45 | __RCSID("$NetBSD: quota.c,v 1.33.2.3 2011/01/28 22:15:36 bouyer Exp $"); | 45 | __RCSID("$NetBSD: quota.c,v 1.33.2.4 2011/01/30 19:38:45 bouyer Exp $"); | |
46 | #endif | 46 | #endif | |
47 | #endif /* not lint */ | 47 | #endif /* not lint */ | |
48 | 48 | |||
49 | /* | 49 | /* | |
50 | * Disk quota reporting program. | 50 | * Disk quota reporting program. | |
51 | */ | 51 | */ | |
52 | #include <sys/param.h> | 52 | #include <sys/param.h> | |
53 | #include <sys/types.h> | 53 | #include <sys/types.h> | |
54 | #include <sys/file.h> | 54 | #include <sys/file.h> | |
55 | #include <sys/stat.h> | 55 | #include <sys/stat.h> | |
56 | #include <sys/mount.h> | 56 | #include <sys/mount.h> | |
57 | #include <sys/socket.h> | 57 | #include <sys/socket.h> | |
58 | 58 | |||
@@ -75,26 +75,27 @@ __RCSID("$NetBSD: quota.c,v 1.33.2.3 201 | @@ -75,26 +75,27 @@ __RCSID("$NetBSD: quota.c,v 1.33.2.3 201 | |||
75 | #include <rpc/pmap_prot.h> | 75 | #include <rpc/pmap_prot.h> | |
76 | #include <rpcsvc/rquota.h> | 76 | #include <rpcsvc/rquota.h> | |
77 | 77 | |||
78 | #include <printquota.h> | 78 | #include <printquota.h> | |
79 | #include <getvfsquota.h> | 79 | #include <getvfsquota.h> | |
80 | 80 | |||
81 | struct quotause { | 81 | struct quotause { | |
82 | struct quotause *next; | 82 | struct quotause *next; | |
83 | long flags; | 83 | long flags; | |
84 | struct quota2_entry q2e; | 84 | struct quota2_entry q2e; | |
85 | char fsname[MAXPATHLEN + 1]; | 85 | char fsname[MAXPATHLEN + 1]; | |
86 | }; | 86 | }; | |
87 | #define FOUND 0x01 | 87 | #define FOUND 0x01 | |
88 | #define QUOTA2 0x02 | |||
88 | 89 | |||
89 | int alldigits(char *); | 90 | int alldigits(char *); | |
90 | int callaurpc(char *, int, int, int, xdrproc_t, void *, xdrproc_t, void *); | 91 | int callaurpc(char *, int, int, int, xdrproc_t, void *, xdrproc_t, void *); | |
91 | int main(int, char **); | 92 | int main(int, char **); | |
92 | int getnfsquota(struct statvfs *, struct fstab *, struct quotause *, | 93 | int getnfsquota(struct statvfs *, struct fstab *, struct quotause *, | |
93 | long, int); | 94 | long, int); | |
94 | struct quotause *getprivs(long id, int quotatype); | 95 | struct quotause *getprivs(long id, int quotatype); | |
95 | void heading(int, u_long, const char *, const char *); | 96 | void heading(int, u_long, const char *, const char *); | |
96 | void showgid(gid_t); | 97 | void showgid(gid_t); | |
97 | void showgrpname(const char *); | 98 | void showgrpname(const char *); | |
98 | void showquotas(int, u_long, const char *); | 99 | void showquotas(int, u_long, const char *); | |
99 | void showuid(uid_t); | 100 | void showuid(uid_t); | |
100 | void showusrname(const char *); | 101 | void showusrname(const char *); | |
@@ -326,27 +327,27 @@ showgrpname(name) | @@ -326,27 +327,27 @@ showgrpname(name) | |||
326 | } | 327 | } | |
327 | } | 328 | } | |
328 | showquotas(GRPQUOTA, grp->gr_gid, name); | 329 | showquotas(GRPQUOTA, grp->gr_gid, name); | |
329 | } | 330 | } | |
330 | 331 | |||
331 | void | 332 | void | |
332 | showquotas(type, id, name) | 333 | showquotas(type, id, name) | |
333 | int type; | 334 | int type; | |
334 | u_long id; | 335 | u_long id; | |
335 | const char *name; | 336 | const char *name; | |
336 | { | 337 | { | |
337 | struct quotause *qup; | 338 | struct quotause *qup; | |
338 | struct quotause *quplist; | 339 | struct quotause *quplist; | |
339 | const char *msgi, *msgb, *nam; | 340 | const char *msgi, *msgb, *nam, *timemsg; | |
340 | int lines = 0; | 341 | int lines = 0; | |
341 | static time_t now; | 342 | static time_t now; | |
342 | 343 | |||
343 | if (now == 0) | 344 | if (now == 0) | |
344 | time(&now); | 345 | time(&now); | |
345 | quplist = getprivs(id, type); | 346 | quplist = getprivs(id, type); | |
346 | for (qup = quplist; qup; qup = qup->next) { | 347 | for (qup = quplist; qup; qup = qup->next) { | |
347 | if (!vflag && | 348 | if (!vflag && | |
348 | qup->q2e.q2e_val[Q2V_BLOCK].q2v_softlimit == UQUAD_MAX && | 349 | qup->q2e.q2e_val[Q2V_BLOCK].q2v_softlimit == UQUAD_MAX && | |
349 | qup->q2e.q2e_val[Q2V_BLOCK].q2v_hardlimit == UQUAD_MAX && | 350 | qup->q2e.q2e_val[Q2V_BLOCK].q2v_hardlimit == UQUAD_MAX && | |
350 | qup->q2e.q2e_val[Q2V_FILE].q2v_softlimit == UQUAD_MAX && | 351 | qup->q2e.q2e_val[Q2V_FILE].q2v_softlimit == UQUAD_MAX && | |
351 | qup->q2e.q2e_val[Q2V_FILE].q2v_hardlimit == UQUAD_MAX) | 352 | qup->q2e.q2e_val[Q2V_FILE].q2v_hardlimit == UQUAD_MAX) | |
352 | continue; | 353 | continue; | |
@@ -386,48 +387,64 @@ showquotas(type, id, name) | @@ -386,48 +387,64 @@ showquotas(type, id, name) | |||
386 | printf("\t%s %s\n", msgb, qup->fsname); | 387 | printf("\t%s %s\n", msgb, qup->fsname); | |
387 | continue; | 388 | continue; | |
388 | } | 389 | } | |
389 | if (vflag || dflag || | 390 | if (vflag || dflag || | |
390 | qup->q2e.q2e_val[Q2V_BLOCK].q2v_cur || | 391 | qup->q2e.q2e_val[Q2V_BLOCK].q2v_cur || | |
391 | qup->q2e.q2e_val[Q2V_FILE].q2v_cur) { | 392 | qup->q2e.q2e_val[Q2V_FILE].q2v_cur) { | |
392 | if (lines++ == 0) | 393 | if (lines++ == 0) | |
393 | heading(type, id, name, ""); | 394 | heading(type, id, name, ""); | |
394 | nam = qup->fsname; | 395 | nam = qup->fsname; | |
395 | if (strlen(qup->fsname) > 4) { | 396 | if (strlen(qup->fsname) > 4) { | |
396 | printf("%s\n", qup->fsname); | 397 | printf("%s\n", qup->fsname); | |
397 | nam = ""; | 398 | nam = ""; | |
398 | } | 399 | } | |
400 | if (msgb) | |||
401 | timemsg = timeprt(now, | |||
402 | qup->q2e.q2e_val[Q2V_BLOCK].q2v_time); | |||
403 | else if ((qup->flags & QUOTA2) != 0 && vflag) | |||
404 | timemsg = timeprt(0, | |||
405 | qup->q2e.q2e_val[Q2V_BLOCK].q2v_grace); | |||
406 | else | |||
407 | timemsg = NULL; | |||
408 | ||||
399 | printf("%12s%9s%c%8s%9s%8s" | 409 | printf("%12s%9s%c%8s%9s%8s" | |
400 | , nam | 410 | , nam | |
401 | , intprt(qup->q2e.q2e_val[Q2V_BLOCK].q2v_cur | 411 | , intprt(qup->q2e.q2e_val[Q2V_BLOCK].q2v_cur | |
402 | ,HN_B, hflag) | 412 | ,HN_B, hflag) | |
403 | , (msgb == NULL) ? ' ' : '*' | 413 | , (msgb == NULL) ? ' ' : '*' | |
404 | , intprt(qup->q2e.q2e_val[Q2V_BLOCK].q2v_softlimit | 414 | , intprt(qup->q2e.q2e_val[Q2V_BLOCK].q2v_softlimit | |
405 | , HN_B, hflag) | 415 | , HN_B, hflag) | |
406 | , intprt(qup->q2e.q2e_val[Q2V_BLOCK].q2v_hardlimit | 416 | , intprt(qup->q2e.q2e_val[Q2V_BLOCK].q2v_hardlimit | |
407 | , HN_B, hflag) | 417 | , HN_B, hflag) | |
408 | , (msgb == NULL) ? "" | 418 | , timemsg); | |
409 | : timeprt(qup->q2e.q2e_val[Q2V_BLOCK].q2v_time)); | 419 | ||
420 | if (msgi) | |||
421 | timemsg = timeprt(now, | |||
422 | qup->q2e.q2e_val[Q2V_FILE].q2v_time); | |||
423 | else if ((qup->flags & QUOTA2) != 0 && vflag) | |||
424 | timemsg = timeprt(0, | |||
425 | qup->q2e.q2e_val[Q2V_FILE].q2v_grace); | |||
426 | else | |||
427 | timemsg = NULL; | |||
428 | ||||
410 | printf("%8s%c%7s%8s%8s\n" | 429 | printf("%8s%c%7s%8s%8s\n" | |
411 | , intprt(qup->q2e.q2e_val[Q2V_FILE].q2v_cur | 430 | , intprt(qup->q2e.q2e_val[Q2V_FILE].q2v_cur | |
412 | , 0, hflag) | 431 | , 0, hflag) | |
413 | , (msgi == NULL) ? ' ' : '*' | 432 | , (msgi == NULL) ? ' ' : '*' | |
414 | , intprt(qup->q2e.q2e_val[Q2V_FILE].q2v_softlimit | 433 | , intprt(qup->q2e.q2e_val[Q2V_FILE].q2v_softlimit | |
415 | , 0, hflag) | 434 | , 0, hflag) | |
416 | , intprt(qup->q2e.q2e_val[Q2V_FILE].q2v_hardlimit | 435 | , intprt(qup->q2e.q2e_val[Q2V_FILE].q2v_hardlimit | |
417 | , 0, hflag) | 436 | , 0, hflag) | |
418 | , (msgi == NULL) ? "" | 437 | , timemsg); | |
419 | : timeprt(qup->q2e.q2e_val[Q2V_FILE].q2v_time) | |||
420 | ); | |||
421 | continue; | 438 | continue; | |
422 | } | 439 | } | |
423 | } | 440 | } | |
424 | if (!qflag && lines == 0) | 441 | if (!qflag && lines == 0) | |
425 | heading(type, id, name, "none"); | 442 | heading(type, id, name, "none"); | |
426 | } | 443 | } | |
427 | 444 | |||
428 | void | 445 | void | |
429 | heading(type, id, name, tag) | 446 | heading(type, id, name, tag) | |
430 | int type; | 447 | int type; | |
431 | u_long id; | 448 | u_long id; | |
432 | const char *name, *tag; | 449 | const char *name, *tag; | |
433 | { | 450 | { | |
@@ -456,52 +473,56 @@ heading(type, id, name, tag) | @@ -456,52 +473,56 @@ heading(type, id, name, tag) | |||
456 | 473 | |||
457 | /* | 474 | /* | |
458 | * Collect the requested quota information. | 475 | * Collect the requested quota information. | |
459 | */ | 476 | */ | |
460 | struct quotause * | 477 | struct quotause * | |
461 | getprivs(id, quotatype) | 478 | getprivs(id, quotatype) | |
462 | long id; | 479 | long id; | |
463 | int quotatype; | 480 | int quotatype; | |
464 | { | 481 | { | |
465 | struct quotause *qup, *quptail; | 482 | struct quotause *qup, *quptail; | |
466 | struct quotause *quphead; | 483 | struct quotause *quphead; | |
467 | struct statvfs *fst; | 484 | struct statvfs *fst; | |
468 | int nfst, i; | 485 | int nfst, i; | |
486 | int8_t version; | |||
469 | 487 | |||
470 | qup = quphead = quptail = NULL; | 488 | qup = quphead = quptail = NULL; | |
471 | 489 | |||
472 | nfst = getmntinfo(&fst, MNT_WAIT); | 490 | nfst = getmntinfo(&fst, MNT_WAIT); | |
473 | if (nfst == 0) | 491 | if (nfst == 0) | |
474 | errx(2, "no filesystems mounted!"); | 492 | errx(2, "no filesystems mounted!"); | |
475 | for (i = 0; i < nfst; i++) { | 493 | for (i = 0; i < nfst; i++) { | |
476 | if (qup == NULL) { | 494 | if (qup == NULL) { | |
477 | if ((qup = | 495 | if ((qup = | |
478 | (struct quotause *)malloc(sizeof *qup)) == NULL) | 496 | (struct quotause *)malloc(sizeof *qup)) == NULL) | |
479 | errx(2, "out of memory"); | 497 | errx(2, "out of memory"); | |
480 | } | 498 | } | |
481 | if (strncmp(fst[i].f_fstypename, "nfs", | 499 | if (strncmp(fst[i].f_fstypename, "nfs", | |
482 | sizeof(fst[i].f_fstypename)) == 0) { | 500 | sizeof(fst[i].f_fstypename)) == 0) { | |
501 | version = 0; | |||
483 | if (getnfsquota(&fst[i], NULL, qup, id, quotatype) == 0) | 502 | if (getnfsquota(&fst[i], NULL, qup, id, quotatype) == 0) | |
484 | continue; | 503 | continue; | |
485 | } else if (strncmp(fst[i].f_fstypename, "ffs", | 504 | } else if (strncmp(fst[i].f_fstypename, "ffs", | |
486 | sizeof(fst[i].f_fstypename)) == 0 && | 505 | sizeof(fst[i].f_fstypename)) == 0 && | |
487 | (fst[i].f_flag & ST_QUOTA) != 0) { | 506 | (fst[i].f_flag & ST_QUOTA) != 0) { | |
488 | if (getvfsquota(fst[i].f_mntonname, &qup->q2e, | 507 | if (getvfsquota(fst[i].f_mntonname, &qup->q2e, &version, | |
489 | id, quotatype, dflag, Dflag) == 0) | 508 | id, quotatype, dflag, Dflag) == 0) | |
490 | continue; | 509 | continue; | |
491 | } else | 510 | } else | |
492 | continue; | 511 | continue; | |
493 | (void)strncpy(qup->fsname, fst[i].f_mntonname, | 512 | (void)strncpy(qup->fsname, fst[i].f_mntonname, | |
494 | sizeof(qup->fsname) - 1); | 513 | sizeof(qup->fsname) - 1); | |
514 | if (version == 2) | |||
515 | qup->flags |= QUOTA2; | |||
495 | if (quphead == NULL) | 516 | if (quphead == NULL) | |
496 | quphead = qup; | 517 | quphead = qup; | |
497 | else | 518 | else | |
498 | quptail->next = qup; | 519 | quptail->next = qup; | |
499 | quptail = qup; | 520 | quptail = qup; | |
500 | quptail->next = 0; | 521 | quptail->next = 0; | |
501 | qup = NULL; | 522 | qup = NULL; | |
502 | } | 523 | } | |
503 | if (qup) | 524 | if (qup) | |
504 | free(qup); | 525 | free(qup); | |
505 | return (quphead); | 526 | return (quphead); | |
506 | } | 527 | } | |
507 | 528 |
--- src/usr.sbin/edquota/edquota.c 2011/01/30 12:38:32 1.29.16.2
+++ src/usr.sbin/edquota/edquota.c 2011/01/30 19:38:45 1.29.16.3
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: edquota.c,v 1.29.16.2 2011/01/30 12:38:32 bouyer Exp $ */ | 1 | /* $NetBSD: edquota.c,v 1.29.16.3 2011/01/30 19:38:45 bouyer Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1980, 1990, 1993 | 4 | * Copyright (c) 1980, 1990, 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. | |
@@ -32,27 +32,27 @@ | @@ -32,27 +32,27 @@ | |||
32 | * SUCH DAMAGE. | 32 | * SUCH DAMAGE. | |
33 | */ | 33 | */ | |
34 | 34 | |||
35 | #include <sys/cdefs.h> | 35 | #include <sys/cdefs.h> | |
36 | #ifndef lint | 36 | #ifndef lint | |
37 | __COPYRIGHT("@(#) Copyright (c) 1980, 1990, 1993\ | 37 | __COPYRIGHT("@(#) Copyright (c) 1980, 1990, 1993\ | |
38 | The Regents of the University of California. All rights reserved."); | 38 | The Regents of the University of California. All rights reserved."); | |
39 | #endif /* not lint */ | 39 | #endif /* not lint */ | |
40 | 40 | |||
41 | #ifndef lint | 41 | #ifndef lint | |
42 | #if 0 | 42 | #if 0 | |
43 | static char sccsid[] = "from: @(#)edquota.c 8.3 (Berkeley) 4/27/95"; | 43 | static char sccsid[] = "from: @(#)edquota.c 8.3 (Berkeley) 4/27/95"; | |
44 | #else | 44 | #else | |
45 | __RCSID("$NetBSD: edquota.c,v 1.29.16.2 2011/01/30 12:38:32 bouyer Exp $"); | 45 | __RCSID("$NetBSD: edquota.c,v 1.29.16.3 2011/01/30 19:38:45 bouyer Exp $"); | |
46 | #endif | 46 | #endif | |
47 | #endif /* not lint */ | 47 | #endif /* not lint */ | |
48 | 48 | |||
49 | /* | 49 | /* | |
50 | * Disk quota editor. | 50 | * Disk quota editor. | |
51 | */ | 51 | */ | |
52 | #include <sys/param.h> | 52 | #include <sys/param.h> | |
53 | #include <sys/stat.h> | 53 | #include <sys/stat.h> | |
54 | #include <sys/file.h> | 54 | #include <sys/file.h> | |
55 | #include <sys/wait.h> | 55 | #include <sys/wait.h> | |
56 | #include <sys/queue.h> | 56 | #include <sys/queue.h> | |
57 | #include <sys/types.h> | 57 | #include <sys/types.h> | |
58 | #include <sys/statvfs.h> | 58 | #include <sys/statvfs.h> | |
@@ -395,38 +395,46 @@ getprivs(long id, int quotatype, const c | @@ -395,38 +395,46 @@ getprivs(long id, int quotatype, const c | |||
395 | quphead = qup; | 395 | quphead = qup; | |
396 | else | 396 | else | |
397 | quptail->next = qup; | 397 | quptail->next = qup; | |
398 | quptail = qup; | 398 | quptail = qup; | |
399 | qup->next = 0; | 399 | qup->next = 0; | |
400 | } | 400 | } | |
401 | return quphead; | 401 | return quphead; | |
402 | } | 402 | } | |
403 | 403 | |||
404 | struct quotause * | 404 | struct quotause * | |
405 | getprivs2(long id, int quotatype, const char *filesys, int defaultq) | 405 | getprivs2(long id, int quotatype, const char *filesys, int defaultq) | |
406 | { | 406 | { | |
407 | struct quotause *qup; | 407 | struct quotause *qup; | |
408 | int8_t version; | |||
409 | ||||
408 | if ((qup = (struct quotause *)malloc(sizeof(*qup))) == NULL) | 410 | if ((qup = (struct quotause *)malloc(sizeof(*qup))) == NULL) | |
409 | errx(2, "out of memory"); | 411 | errx(2, "out of memory"); | |
410 | qup->qfname = NULL; | 412 | memset(qup, 0, sizeof(*qup)); | |
411 | strcpy(qup->fsname, filesys); | 413 | strcpy(qup->fsname, filesys); | |
412 | qup->flags |= QUOTA2; | |||
413 | if (defaultq) | 414 | if (defaultq) | |
414 | qup->flags |= DEFAULT; | 415 | qup->flags |= DEFAULT; | |
415 | if (!getvfsquota(filesys, &qup->q2e, id, quotatype, defaultq, Dflag)) { | 416 | if (!getvfsquota(filesys, &qup->q2e, &version, | |
417 | id, quotatype, defaultq, Dflag)) { | |||
416 | /* no entry, get default entry */ | 418 | /* no entry, get default entry */ | |
417 | if (!getvfsquota(filesys, &qup->q2e, id, quotatype, 1, Dflag)) | 419 | if (!getvfsquota(filesys, &qup->q2e, &version, | |
420 | id, quotatype, 1, Dflag)) { | |||
421 | free(qup); | |||
418 | return NULL; | 422 | return NULL; | |
423 | } | |||
419 | } | 424 | } | |
425 | if (version == 2) | |||
426 | qup->flags |= QUOTA2; | |||
427 | qup->q2e.q2e_uid = id; | |||
420 | return qup; | 428 | return qup; | |
421 | } | 429 | } | |
422 | 430 | |||
423 | struct quotause * | 431 | struct quotause * | |
424 | getprivs1(long id, int quotatype, const char *filesys) | 432 | getprivs1(long id, int quotatype, const char *filesys) | |
425 | { | 433 | { | |
426 | struct fstab *fs; | 434 | struct fstab *fs; | |
427 | char *qfpathname; | 435 | char *qfpathname; | |
428 | struct quotause *qup; | 436 | struct quotause *qup; | |
429 | struct dqblk dqblk; | 437 | struct dqblk dqblk; | |
430 | int fd; | 438 | int fd; | |
431 | 439 | |||
432 | setfsent(); | 440 | setfsent(); | |
@@ -485,27 +493,27 @@ getprivs1(long id, int quotatype, const | @@ -485,27 +493,27 @@ getprivs1(long id, int quotatype, const | |||
485 | dqblk2q2e(&dqblk, &qup->q2e); | 493 | dqblk2q2e(&dqblk, &qup->q2e); | |
486 | return (qup); | 494 | return (qup); | |
487 | } | 495 | } | |
488 | 496 | |||
489 | /* | 497 | /* | |
490 | * Store the requested quota information. | 498 | * Store the requested quota information. | |
491 | */ | 499 | */ | |
492 | void | 500 | void | |
493 | putprivs(long id, int quotatype, struct quotause *quplist) | 501 | putprivs(long id, int quotatype, struct quotause *quplist) | |
494 | { | 502 | { | |
495 | struct quotause *qup; | 503 | struct quotause *qup; | |
496 | 504 | |||
497 | for (qup = quplist; qup; qup = qup->next) { | 505 | for (qup = quplist; qup; qup = qup->next) { | |
498 | if (qup->flags & QUOTA2) | 506 | if (qup->qfname == NULL) | |
499 | putprivs2(id, quotatype, qup); | 507 | putprivs2(id, quotatype, qup); | |
500 | else | 508 | else | |
501 | putprivs1(id, quotatype, qup); | 509 | putprivs1(id, quotatype, qup); | |
502 | } | 510 | } | |
503 | } | 511 | } | |
504 | 512 | |||
505 | void | 513 | void | |
506 | putprivs2(long id, int quotatype, struct quotause *qup) | 514 | putprivs2(long id, int quotatype, struct quotause *qup) | |
507 | { | 515 | { | |
508 | 516 | |||
509 | prop_dictionary_t dict, data, cmd; | 517 | prop_dictionary_t dict, data, cmd; | |
510 | prop_array_t cmds, datas; | 518 | prop_array_t cmds, datas; | |
511 | struct plistref pref; | 519 | struct plistref pref; | |
@@ -1031,27 +1039,27 @@ alldigits(s) | @@ -1031,27 +1039,27 @@ alldigits(s) | |||
1031 | const char *s; | 1039 | const char *s; | |
1032 | { | 1040 | { | |
1033 | int c; | 1041 | int c; | |
1034 | 1042 | |||
1035 | c = *s++; | 1043 | c = *s++; | |
1036 | do { | 1044 | do { | |
1037 | if (!isdigit(c)) | 1045 | if (!isdigit(c)) | |
1038 | return (0); | 1046 | return (0); | |
1039 | } while ((c = *s++) != 0); | 1047 | } while ((c = *s++) != 0); | |
1040 | return (1); | 1048 | return (1); | |
1041 | } | 1049 | } | |
1042 | 1050 | |||
1043 | /* | 1051 | /* | |
1044 | * Check to see if a particular quota is to be enabled. | 1052 | * Check to see if a particular legacy quota is to be enabled in fstab | |
1045 | */ | 1053 | */ | |
1046 | int | 1054 | int | |
1047 | hasquota(fs, type, qfnamep) | 1055 | hasquota(fs, type, qfnamep) | |
1048 | struct fstab *fs; | 1056 | struct fstab *fs; | |
1049 | int type; | 1057 | int type; | |
1050 | char **qfnamep; | 1058 | char **qfnamep; | |
1051 | { | 1059 | { | |
1052 | char *opt; | 1060 | char *opt; | |
1053 | char *cp; | 1061 | char *cp; | |
1054 | static char initname, usrname[100], grpname[100]; | 1062 | static char initname, usrname[100], grpname[100]; | |
1055 | char *buf; | 1063 | char *buf; | |
1056 | 1064 | |||
1057 | if (!initname) { | 1065 | if (!initname) { |
--- src/usr.sbin/repquota/repquota.c 2011/01/29 11:04:43 1.25.2.2
+++ src/usr.sbin/repquota/repquota.c 2011/01/30 19:38:45 1.25.2.3
@@ -30,27 +30,27 @@ | @@ -30,27 +30,27 @@ | |||
30 | * SUCH DAMAGE. | 30 | * SUCH DAMAGE. | |
31 | */ | 31 | */ | |
32 | 32 | |||
33 | #include <sys/cdefs.h> | 33 | #include <sys/cdefs.h> | |
34 | #ifndef lint | 34 | #ifndef lint | |
35 | __COPYRIGHT("@(#) Copyright (c) 1980, 1990, 1993\ | 35 | __COPYRIGHT("@(#) Copyright (c) 1980, 1990, 1993\ | |
36 | The Regents of the University of California. All rights reserved."); | 36 | The Regents of the University of California. All rights reserved."); | |
37 | #endif /* not lint */ | 37 | #endif /* not lint */ | |
38 | 38 | |||
39 | #ifndef lint | 39 | #ifndef lint | |
40 | #if 0 | 40 | #if 0 | |
41 | static char sccsid[] = "@(#)repquota.c 8.2 (Berkeley) 11/22/94"; | 41 | static char sccsid[] = "@(#)repquota.c 8.2 (Berkeley) 11/22/94"; | |
42 | #else | 42 | #else | |
43 | __RCSID("$NetBSD: repquota.c,v 1.25.2.2 2011/01/29 11:04:43 bouyer Exp $"); | 43 | __RCSID("$NetBSD: repquota.c,v 1.25.2.3 2011/01/30 19:38:45 bouyer Exp $"); | |
44 | #endif | 44 | #endif | |
45 | #endif /* not lint */ | 45 | #endif /* not lint */ | |
46 | 46 | |||
47 | /* | 47 | /* | |
48 | * Quota report | 48 | * Quota report | |
49 | */ | 49 | */ | |
50 | #include <sys/param.h> | 50 | #include <sys/param.h> | |
51 | #include <sys/stat.h> | 51 | #include <sys/stat.h> | |
52 | #include <sys/types.h> | 52 | #include <sys/types.h> | |
53 | #include <sys/statvfs.h> | 53 | #include <sys/statvfs.h> | |
54 | #include <prop/proplib.h> | 54 | #include <prop/proplib.h> | |
55 | #include <sys/quota.h> | 55 | #include <sys/quota.h> | |
56 | 56 | |||
@@ -88,27 +88,27 @@ int vflag = 0; /* verbose */ | @@ -88,27 +88,27 @@ int vflag = 0; /* verbose */ | |||
88 | int aflag = 0; /* all file systems */ | 88 | int aflag = 0; /* all file systems */ | |
89 | int Dflag = 0; /* debug */ | 89 | int Dflag = 0; /* debug */ | |
90 | int hflag = 0; /* debug */ | 90 | int hflag = 0; /* debug */ | |
91 | 91 | |||
92 | struct fileusage *addid(u_long, int, const char *); | 92 | struct fileusage *addid(u_long, int, const char *); | |
93 | int hasquota(struct fstab *, int, char **); | 93 | int hasquota(struct fstab *, int, char **); | |
94 | struct fileusage *lookup(u_long, int); | 94 | struct fileusage *lookup(u_long, int); | |
95 | int main(int, char **); | 95 | int main(int, char **); | |
96 | int oneof(const char *, char **, int); | 96 | int oneof(const char *, char **, int); | |
97 | int repquota(const struct statvfs *, int); | 97 | int repquota(const struct statvfs *, int); | |
98 | int repquota2(const struct statvfs *, int); | 98 | int repquota2(const struct statvfs *, int); | |
99 | int repquota1(const struct statvfs *, int); | 99 | int repquota1(const struct statvfs *, int); | |
100 | void usage(void); | 100 | void usage(void); | |
101 | void printquotas(int, const struct statvfs *); | 101 | void printquotas(int, const struct statvfs *, int); | |
102 | void dqblk2q2e(const struct dqblk *, struct quota2_entry *); | 102 | void dqblk2q2e(const struct dqblk *, struct quota2_entry *); | |
103 | 103 | |||
104 | int | 104 | int | |
105 | main(argc, argv) | 105 | main(argc, argv) | |
106 | int argc; | 106 | int argc; | |
107 | char **argv; | 107 | char **argv; | |
108 | { | 108 | { | |
109 | struct passwd *pw; | 109 | struct passwd *pw; | |
110 | struct group *gr; | 110 | struct group *gr; | |
111 | int gflag = 0, uflag = 0, errs = 0; | 111 | int gflag = 0, uflag = 0, errs = 0; | |
112 | long i, argnum, done = 0; | 112 | long i, argnum, done = 0; | |
113 | int ch; | 113 | int ch; | |
114 | struct statvfs *fst; | 114 | struct statvfs *fst; | |
@@ -204,115 +204,135 @@ repquota(const struct statvfs *vfs, int | @@ -204,115 +204,135 @@ repquota(const struct statvfs *vfs, int | |||
204 | { | 204 | { | |
205 | if (repquota2(vfs, type) != 0) | 205 | if (repquota2(vfs, type) != 0) | |
206 | return (repquota1(vfs, type)); | 206 | return (repquota1(vfs, type)); | |
207 | return 0; | 207 | return 0; | |
208 | } | 208 | } | |
209 | 209 | |||
210 | int | 210 | int | |
211 | repquota2(const struct statvfs *vfs, int type) | 211 | repquota2(const struct statvfs *vfs, int type) | |
212 | { | 212 | { | |
213 | prop_dictionary_t dict, data, cmd; | 213 | prop_dictionary_t dict, data, cmd; | |
214 | prop_array_t cmds, datas; | 214 | prop_array_t cmds, datas; | |
215 | struct plistref pref; | 215 | struct plistref pref; | |
216 | int error; | 216 | int error; | |
217 | int8_t error8; | 217 | int8_t error8, version = 0; | |
218 | prop_object_iterator_t iter; | 218 | prop_object_iterator_t cmditer, dataiter; | |
219 | struct quota2_entry *q2ep; | 219 | struct quota2_entry *q2ep; | |
220 | struct fileusage *fup; | 220 | struct fileusage *fup; | |
221 | const char *strid; | 221 | const char *strid; | |
222 | uint32_t id; | 222 | uint32_t id; | |
223 | 223 | |||
224 | dict = quota2_prop_create(); | 224 | dict = quota2_prop_create(); | |
225 | cmds = prop_array_create(); | 225 | cmds = prop_array_create(); | |
226 | datas = prop_array_create(); | 226 | datas = prop_array_create(); | |
227 | 227 | |||
228 | if (dict == NULL || cmds == NULL || datas == NULL) | 228 | if (dict == NULL || cmds == NULL || datas == NULL) | |
229 | errx(1, "can't allocate proplist"); | 229 | errx(1, "can't allocate proplist"); | |
230 | if (!quota2_prop_add_command(cmds, "getall", qfextension[type], datas)) | 230 | if (!quota2_prop_add_command(cmds, "getall", qfextension[type], datas)) | |
231 | err(1, "prop_add_command"); | 231 | err(1, "prop_add_command"); | |
232 | if (!quota2_prop_add_command(cmds, "get version", qfextension[type], | |||
233 | prop_array_create())) | |||
234 | err(1, "prop_add_command"); | |||
232 | if (!prop_dictionary_set(dict, "commands", cmds)) | 235 | if (!prop_dictionary_set(dict, "commands", cmds)) | |
233 | err(1, "prop_dictionary_set(command)"); | 236 | err(1, "prop_dictionary_set(command)"); | |
234 | if (Dflag) | 237 | if (Dflag) | |
235 | printf("message to kernel:\n%s\n", | 238 | printf("message to kernel:\n%s\n", | |
236 | prop_dictionary_externalize(dict)); | 239 | prop_dictionary_externalize(dict)); | |
237 | if (!prop_dictionary_send_syscall(dict, &pref)) | 240 | if (!prop_dictionary_send_syscall(dict, &pref)) | |
238 | err(1, "prop_dictionary_send_syscall"); | 241 | err(1, "prop_dictionary_send_syscall"); | |
239 | prop_object_release(dict); | 242 | prop_object_release(dict); | |
240 | 243 | |||
241 | if (quotactl(vfs->f_mntonname, &pref) != 0) | 244 | if (quotactl(vfs->f_mntonname, &pref) != 0) | |
242 | err(1, "quotactl"); | 245 | err(1, "quotactl"); | |
243 | 246 | |||
244 | if ((error = prop_dictionary_recv_syscall(&pref, &dict)) != 0) { | 247 | if ((error = prop_dictionary_recv_syscall(&pref, &dict)) != 0) { | |
245 | errx(1, "prop_dictionary_recv_syscall: %s\n", | 248 | errx(1, "prop_dictionary_recv_syscall: %s\n", | |
246 | strerror(error)); | 249 | strerror(error)); | |
247 | } | 250 | } | |
248 | if (Dflag) | 251 | if (Dflag) | |
249 | printf("reply from kernel:\n%s\n", | 252 | printf("reply from kernel:\n%s\n", | |
250 | prop_dictionary_externalize(dict)); | 253 | prop_dictionary_externalize(dict)); | |
251 | if ((error = quota2_get_cmds(dict, &cmds)) != 0) { | 254 | if ((error = quota2_get_cmds(dict, &cmds)) != 0) { | |
252 | errx(1, "quota2_get_cmds: %s\n", | 255 | errx(1, "quota2_get_cmds: %s\n", | |
253 | strerror(error)); | 256 | strerror(error)); | |
254 | } | 257 | } | |
255 | /* only one command, no need to iter */ | 258 | cmditer = prop_array_iterator(cmds); | |
256 | cmd = prop_array_get(cmds, 0); | 259 | if (cmditer == NULL) | |
257 | if (cmd == NULL) | 260 | err(1, "prop_array_iterator(cmds)"); | |
258 | err(1, "prop_array_get(cmd)"); | 261 | ||
259 | 262 | while ((cmd = prop_object_iterator_next(cmditer)) != NULL) { | ||
260 | if (!prop_dictionary_get_int8(cmd, "return", &error8)) | 263 | const char *cmdstr; | |
261 | err(1, "prop_get(return)"); | 264 | if (!prop_dictionary_get_cstring_nocopy(cmd, "command", | |
262 | 265 | &cmdstr)) | ||
263 | if (error8) { | 266 | err(1, "prop_get(command)"); | |
264 | prop_object_release(dict); | 267 | ||
265 | if (error8 != EOPNOTSUPP) { | 268 | if (!prop_dictionary_get_int8(cmd, "return", &error8)) | |
266 | fprintf(stderr, "get %s quotas: %s\n", | 269 | err(1, "prop_get(return)"); | |
267 | qfextension[type], strerror(error8)); | 270 | ||
268 | } | 271 | if (error8) { | |
269 | return (error8); | 272 | prop_object_release(dict); | |
270 | } | 273 | if (error8 != EOPNOTSUPP) { | |
271 | datas = prop_dictionary_get(cmd, "data"); | 274 | fprintf(stderr, "get %s quotas: %s\n", | |
272 | if (datas == NULL) | 275 | qfextension[type], strerror(error8)); | |
273 | err(1, "prop_dict_get(datas)"); | |||
274 | ||||
275 | iter = prop_array_iterator(datas); | |||
276 | if (iter == NULL) | |||
277 | err(1, "prop_array_iterator"); | |||
278 | ||||
279 | while ((data = prop_object_iterator_next(iter)) != NULL) { | |||
280 | strid = NULL; | |||
281 | if (!prop_dictionary_get_uint32(data, "id", &id)) { | |||
282 | if (!prop_dictionary_get_cstring_nocopy(data, "id", | |||
283 | &strid)) | |||
284 | errx(1, "can't find id in quota entry"); | |||
285 | if (strcmp(strid, "default") != 0) { | |||
286 | errx(1, "wrong id string %s in quota entry", | |||
287 | strid); | |||
288 | } | 276 | } | |
289 | q2ep = &defaultq2e[type]; | 277 | return (error8); | |
290 | } else { | |||
291 | if ((fup = lookup(id, type)) == 0) | |||
292 | fup = addid(id, type, (char *)0); | |||
293 | q2ep = &fup->fu_q2e; | |||
294 | q2ep->q2e_uid = id; | |||
295 | } | 278 | } | |
296 | 279 | datas = prop_dictionary_get(cmd, "data"); | ||
297 | error = quota2_dict_get_q2e_usage(data, q2ep); | 280 | if (datas == NULL) | |
298 | if (error) { | 281 | err(1, "prop_dict_get(datas)"); | |
299 | errx(1, "quota2_dict_get_q2e_usage: %s\n", | 282 | ||
300 | strerror(error)); | 283 | if (strcmp("get version", cmdstr) == 0) { | |
284 | data = prop_array_get(datas, 0); | |||
285 | if (data == NULL) | |||
286 | err(1, "prop_array_get(version)"); | |||
287 | if (!prop_dictionary_get_int8(data, "version", | |||
288 | &version)) | |||
289 | err(1, "prop_get_int8(version)"); | |||
290 | continue; | |||
291 | } | |||
292 | dataiter = prop_array_iterator(datas); | |||
293 | if (dataiter == NULL) | |||
294 | err(1, "prop_array_iterator"); | |||
295 | ||||
296 | while ((data = prop_object_iterator_next(dataiter)) != NULL) { | |||
297 | strid = NULL; | |||
298 | if (!prop_dictionary_get_uint32(data, "id", &id)) { | |||
299 | if (!prop_dictionary_get_cstring_nocopy(data, | |||
300 | "id", &strid)) | |||
301 | errx(1, "can't find id in quota entry"); | |||
302 | if (strcmp(strid, "default") != 0) { | |||
303 | errx(1, | |||
304 | "wrong id string %s in quota entry", | |||
305 | strid); | |||
306 | } | |||
307 | q2ep = &defaultq2e[type]; | |||
308 | } else { | |||
309 | if ((fup = lookup(id, type)) == 0) | |||
310 | fup = addid(id, type, (char *)0); | |||
311 | q2ep = &fup->fu_q2e; | |||
312 | q2ep->q2e_uid = id; | |||
313 | } | |||
314 | ||||
315 | error = quota2_dict_get_q2e_usage(data, q2ep); | |||
316 | if (error) { | |||
317 | errx(1, "quota2_dict_get_q2e_usage: %s\n", | |||
318 | strerror(error)); | |||
319 | } | |||
301 | } | 320 | } | |
321 | prop_object_iterator_release(dataiter); | |||
302 | } | 322 | } | |
303 | prop_object_iterator_release(iter); | 323 | prop_object_iterator_release(cmditer); | |
304 | prop_object_release(dict); | 324 | prop_object_release(dict); | |
305 | printquotas(type, vfs); | 325 | printquotas(type, vfs, version); | |
306 | return (0); | 326 | return (0); | |
307 | } | 327 | } | |
308 | 328 | |||
309 | int repquota1(const struct statvfs *vfs, int type) | 329 | int repquota1(const struct statvfs *vfs, int type) | |
310 | { | 330 | { | |
311 | char *qfpathname; | 331 | char *qfpathname; | |
312 | struct fstab *fs; | 332 | struct fstab *fs; | |
313 | struct fileusage *fup; | 333 | struct fileusage *fup; | |
314 | FILE *qf; | 334 | FILE *qf; | |
315 | u_long id; | 335 | u_long id; | |
316 | struct dqblk dqbuf; | 336 | struct dqblk dqbuf; | |
317 | 337 | |||
318 | #if 0 | 338 | #if 0 | |
@@ -343,86 +363,109 @@ int repquota1(const struct statvfs *vfs, | @@ -343,86 +363,109 @@ int repquota1(const struct statvfs *vfs, | |||
343 | return (1); | 363 | return (1); | |
344 | } | 364 | } | |
345 | for (id = 0; ; id++) { | 365 | for (id = 0; ; id++) { | |
346 | fread(&dqbuf, sizeof(struct dqblk), 1, qf); | 366 | fread(&dqbuf, sizeof(struct dqblk), 1, qf); | |
347 | if (feof(qf)) | 367 | if (feof(qf)) | |
348 | break; | 368 | break; | |
349 | if (dqbuf.dqb_curinodes == 0 && dqbuf.dqb_curblocks == 0) | 369 | if (dqbuf.dqb_curinodes == 0 && dqbuf.dqb_curblocks == 0) | |
350 | continue; | 370 | continue; | |
351 | if ((fup = lookup(id, type)) == 0) | 371 | if ((fup = lookup(id, type)) == 0) | |
352 | fup = addid(id, type, (char *)0); | 372 | fup = addid(id, type, (char *)0); | |
353 | dqblk2q2e(&dqbuf, &fup->fu_q2e); | 373 | dqblk2q2e(&dqbuf, &fup->fu_q2e); | |
354 | } | 374 | } | |
355 | fclose(qf); | 375 | fclose(qf); | |
356 | printquotas(type, vfs); | 376 | printquotas(type, vfs, 1); | |
357 | return (0); | 377 | return (0); | |
358 | } | 378 | } | |
359 | 379 | |||
360 | void | 380 | void | |
361 | printquotas(int type, const struct statvfs *vfs) | 381 | printquotas(int type, const struct statvfs *vfs, int version) | |
362 | { | 382 | { | |
363 | static int multiple = 0; | 383 | static int multiple = 0; | |
364 | u_long id; | 384 | u_long id; | |
365 | struct fileusage *fup; | 385 | struct fileusage *fup; | |
386 | const char *timemsg; | |||
387 | static time_t now; | |||
388 | ||||
389 | if (now == 0) | |||
390 | time(&now); | |||
366 | 391 | |||
367 | if (multiple++) | 392 | if (multiple++) | |
368 | printf("\n"); | 393 | printf("\n"); | |
369 | if (vflag) | 394 | if (vflag) | |
370 | fprintf(stdout, "*** Report for %s quotas on %s (%s)\n", | 395 | fprintf(stdout, | |
371 | qfextension[type], vfs->f_mntonname, vfs->f_mntfromname); | 396 | "*** Report for %s quotas on %s (%s, version %d)\n", | |
397 | qfextension[type], vfs->f_mntonname, vfs->f_mntfromname, | |||
398 | version); | |||
372 | printf(" Block limits File limits\n"); | 399 | printf(" Block limits File limits\n"); | |
373 | printf(type == USRQUOTA ? "User " : "Group"); | 400 | printf(type == USRQUOTA ? "User " : "Group"); | |
374 | printf(" used soft hard grace used soft hard grace\n"); | 401 | printf(" used soft hard grace used soft hard grace\n"); | |
375 | for (id = 0; id <= highid[type]; id++) { | 402 | for (id = 0; id <= highid[type]; id++) { | |
376 | fup = lookup(id, type); | 403 | fup = lookup(id, type); | |
377 | if (fup == 0) | 404 | if (fup == 0) | |
378 | continue; | 405 | continue; | |
379 | if (fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_cur == 0 && | 406 | if (fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_cur == 0 && | |
380 | fup->fu_q2e.q2e_val[Q2V_FILE].q2v_cur == 0) | 407 | fup->fu_q2e.q2e_val[Q2V_FILE].q2v_cur == 0) | |
381 | continue; | 408 | continue; | |
382 | if (strlen(fup->fu_name) > 9) | 409 | if (strlen(fup->fu_name) > 9) | |
383 | printf("%s ", fup->fu_name); | 410 | printf("%s ", fup->fu_name); | |
384 | else | 411 | else | |
385 | printf("%-10s", fup->fu_name); | 412 | printf("%-10s", fup->fu_name); | |
413 | ||||
414 | if (fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_softlimit && | |||
415 | fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_cur >= | |||
416 | fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_softlimit) | |||
417 | timemsg = timeprt(now, | |||
418 | fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_time); | |||
419 | else if (vflag && version == 2) | |||
420 | timemsg = timeprt(0, | |||
421 | fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_grace); | |||
422 | else | |||
423 | timemsg = ""; | |||
424 | ||||
386 | printf("%c%c%9s%9s%9s%7s", | 425 | printf("%c%c%9s%9s%9s%7s", | |
387 | fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_softlimit && | 426 | fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_softlimit && | |
388 | fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_cur >= | 427 | fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_cur >= | |
389 | fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_softlimit ? | 428 | fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_softlimit ? | |
390 | '+' : '-', | 429 | '+' : '-', | |
391 | fup->fu_q2e.q2e_val[Q2V_FILE].q2v_softlimit && | 430 | fup->fu_q2e.q2e_val[Q2V_FILE].q2v_softlimit && | |
392 | fup->fu_q2e.q2e_val[Q2V_FILE].q2v_cur >= | 431 | fup->fu_q2e.q2e_val[Q2V_FILE].q2v_cur >= | |
393 | fup->fu_q2e.q2e_val[Q2V_FILE].q2v_softlimit ? | 432 | fup->fu_q2e.q2e_val[Q2V_FILE].q2v_softlimit ? | |
394 | '+' : '-', | 433 | '+' : '-', | |
395 | intprt(fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_cur, | 434 | intprt(fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_cur, | |
396 | HN_B, hflag), | 435 | HN_B, hflag), | |
397 | intprt(fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_softlimit, | 436 | intprt(fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_softlimit, | |
398 | HN_B, hflag), | 437 | HN_B, hflag), | |
399 | intprt(fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_hardlimit, | 438 | intprt(fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_hardlimit, | |
400 | HN_B, hflag), | 439 | HN_B, hflag), | |
401 | (fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_softlimit && | 440 | timemsg); | |
402 | fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_cur >= | 441 | if (fup->fu_q2e.q2e_val[Q2V_FILE].q2v_softlimit && | |
403 | fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_softlimit) ? | 442 | fup->fu_q2e.q2e_val[Q2V_FILE].q2v_cur >= | |
404 | timeprt(fup->fu_q2e.q2e_val[Q2V_BLOCK].q2v_time) : ""); | 443 | fup->fu_q2e.q2e_val[Q2V_FILE].q2v_softlimit) | |
444 | timemsg = timeprt(now, | |||
445 | fup->fu_q2e.q2e_val[Q2V_FILE].q2v_time); | |||
446 | else if (vflag && version == 2) | |||
447 | timemsg = timeprt(0, | |||
448 | fup->fu_q2e.q2e_val[Q2V_FILE].q2v_grace); | |||
449 | else | |||
450 | timemsg = ""; | |||
405 | printf(" %8s%8s%8s%7s\n", | 451 | printf(" %8s%8s%8s%7s\n", | |
406 | intprt(fup->fu_q2e.q2e_val[Q2V_FILE].q2v_cur, | 452 | intprt(fup->fu_q2e.q2e_val[Q2V_FILE].q2v_cur, | |
407 | 0, hflag), | 453 | 0, hflag), | |
408 | intprt(fup->fu_q2e.q2e_val[Q2V_FILE].q2v_softlimit, | 454 | intprt(fup->fu_q2e.q2e_val[Q2V_FILE].q2v_softlimit, | |
409 | 0, hflag), | 455 | 0, hflag), | |
410 | intprt(fup->fu_q2e.q2e_val[Q2V_FILE].q2v_hardlimit, | 456 | intprt(fup->fu_q2e.q2e_val[Q2V_FILE].q2v_hardlimit, | |
411 | 0, hflag), | 457 | 0, hflag), | |
412 | (fup->fu_q2e.q2e_val[Q2V_FILE].q2v_softlimit && | 458 | timemsg); | |
413 | fup->fu_q2e.q2e_val[Q2V_FILE].q2v_cur >= | |||
414 | fup->fu_q2e.q2e_val[Q2V_FILE].q2v_softlimit) ? | |||
415 | timeprt(fup->fu_q2e.q2e_val[Q2V_FILE].q2v_time) : ""); | |||
416 | memset(&fup->fu_q2e, 0, sizeof(fup->fu_q2e)); | 459 | memset(&fup->fu_q2e, 0, sizeof(fup->fu_q2e)); | |
417 | } | 460 | } | |
418 | } | 461 | } | |
419 | 462 | |||
420 | /* | 463 | /* | |
421 | * Check to see if target appears in list of size cnt. | 464 | * Check to see if target appears in list of size cnt. | |
422 | */ | 465 | */ | |
423 | int | 466 | int | |
424 | oneof(target, list, cnt) | 467 | oneof(target, list, cnt) | |
425 | const char *target; | 468 | const char *target; | |
426 | char *list[]; | 469 | char *list[]; | |
427 | int cnt; | 470 | int cnt; | |
428 | { | 471 | { |