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