1 /* $NetBSD: quota_cursor.c,v 1.6 2012/02/01 05:46:46 dholland Exp $ */
2 /*-
3 * Copyright (c) 2011 The NetBSD Foundation, Inc.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to The NetBSD Foundation
7 * by David A. Holland.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
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
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
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
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
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include <sys/cdefs.h>
32 __RCSID("$NetBSD: quota_cursor.c,v 1.6 2012/02/01 05:46:46 dholland Exp $");
33
34 #include <stdlib.h>
35 #include <errno.h>
36
37 #include <quota.h>
38 #include "quotapvt.h"
39
40 struct quotacursor *
quota_opencursor(struct quotahandle * qh)41 quota_opencursor(struct quotahandle *qh)
42 {
43 struct quotacursor *qc;
44 unsigned restrictions;
45 int serrno;
46
47 switch (qh->qh_mode) {
48 case QUOTA_MODE_NFS:
49 errno = EOPNOTSUPP;
50 return NULL;
51
52 case QUOTA_MODE_OLDFILES:
53 restrictions = QUOTA_RESTRICT_NEEDSQUOTACHECK;
54 break;
55
56 case QUOTA_MODE_KERNEL:
57 restrictions = __quota_kernel_getrestrictions(qh);
58 break;
59
60 default:
61 errno = EINVAL;
62 return NULL;
63 }
64
65 /*
66 * For the time being at least the version 1 kernel code
67 * cannot do cursors.
68 */
69 if ((restrictions & QUOTA_RESTRICT_NEEDSQUOTACHECK) != 0 &&
70 !qh->qh_oldfilesopen) {
71 if (__quota_oldfiles_initialize(qh)) {
72 return NULL;
73 }
74 }
75
76 qc = malloc(sizeof(*qc));
77 if (qc == NULL) {
78 return NULL;
79 }
80
81 qc->qc_qh = qh;
82
83 if ((restrictions & QUOTA_RESTRICT_NEEDSQUOTACHECK) != 0) {
84 qc->qc_type = QC_OLDFILES;
85 qc->u.qc_oldfiles = __quota_oldfiles_cursor_create(qh);
86 if (qc->u.qc_oldfiles == NULL) {
87 serrno = errno;
88 free(qc);
89 errno = serrno;
90 return NULL;
91 }
92 } else {
93 qc->qc_type = QC_KERNEL;
94 qc->u.qc_kernel = __quota_kernel_cursor_create(qh);
95 if (qc->u.qc_kernel == NULL) {
96 serrno = errno;
97 free(qc);
98 errno = serrno;
99 return NULL;
100 }
101 }
102 return qc;
103 }
104
105 void
quotacursor_close(struct quotacursor * qc)106 quotacursor_close(struct quotacursor *qc)
107 {
108 switch (qc->qc_type) {
109 case QC_OLDFILES:
110 __quota_oldfiles_cursor_destroy(qc->u.qc_oldfiles);
111 break;
112 case QC_KERNEL:
113 __quota_kernel_cursor_destroy(qc->qc_qh, qc->u.qc_kernel);
114 break;
115 }
116 free(qc);
117 }
118
119 int
quotacursor_skipidtype(struct quotacursor * qc,int idtype)120 quotacursor_skipidtype(struct quotacursor *qc, int idtype)
121 {
122 switch (qc->qc_type) {
123 case QC_OLDFILES:
124 return __quota_oldfiles_cursor_skipidtype(qc->u.qc_oldfiles,
125 idtype);
126 case QC_KERNEL:
127 return __quota_kernel_cursor_skipidtype(qc->qc_qh,
128 qc->u.qc_kernel,
129 idtype);
130 }
131 errno = EINVAL;
132 return -1;
133 }
134
135 int
quotacursor_get(struct quotacursor * qc,struct quotakey * qk_ret,struct quotaval * qv_ret)136 quotacursor_get(struct quotacursor *qc,
137 struct quotakey *qk_ret, struct quotaval *qv_ret)
138 {
139 switch (qc->qc_type) {
140 case QC_OLDFILES:
141 return __quota_oldfiles_cursor_get(qc->qc_qh,
142 qc->u.qc_oldfiles,
143 qk_ret, qv_ret);
144 case QC_KERNEL:
145 return __quota_kernel_cursor_get(qc->qc_qh, qc->u.qc_kernel,
146 qk_ret, qv_ret);
147 }
148 errno = EINVAL;
149 return -1;
150 }
151
152 int
quotacursor_getn(struct quotacursor * qc,struct quotakey * keys,struct quotaval * vals,unsigned maxnum)153 quotacursor_getn(struct quotacursor *qc,
154 struct quotakey *keys, struct quotaval *vals,
155 unsigned maxnum)
156 {
157 switch (qc->qc_type) {
158 case QC_OLDFILES:
159 return __quota_oldfiles_cursor_getn(qc->qc_qh,
160 qc->u.qc_oldfiles,
161 keys, vals, maxnum);
162 case QC_KERNEL:
163 return __quota_kernel_cursor_getn(qc->qc_qh, qc->u.qc_kernel,
164 keys, vals, maxnum);
165 }
166 errno = EINVAL;
167 return -1;
168 }
169
170 int
quotacursor_atend(struct quotacursor * qc)171 quotacursor_atend(struct quotacursor *qc)
172 {
173 switch (qc->qc_type) {
174 case QC_OLDFILES:
175 return __quota_oldfiles_cursor_atend(qc->u.qc_oldfiles);
176
177 case QC_KERNEL:
178 return __quota_kernel_cursor_atend(qc->qc_qh, qc->u.qc_kernel);
179 }
180 errno = EINVAL;
181 return -1;
182 }
183
184 int
quotacursor_rewind(struct quotacursor * qc)185 quotacursor_rewind(struct quotacursor *qc)
186 {
187 switch (qc->qc_type) {
188 case QC_OLDFILES:
189 return __quota_oldfiles_cursor_rewind(qc->u.qc_oldfiles);
190 case QC_KERNEL:
191 return __quota_kernel_cursor_rewind(qc->qc_qh,qc->u.qc_kernel);
192 }
193 errno = EINVAL;
194 return -1;
195 }
196