xref: /netbsd/lib/libquota/quota_cursor.c (revision 2f739562)
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