1263363Semaste/*	$NetBSD: quota_cursor.c,v 1.5 2012/02/01 05:34:40 dholland Exp $	*/
2254721Semaste/*-
3254721Semaste * Copyright (c) 2011 The NetBSD Foundation, Inc.
4254721Semaste * All rights reserved.
5254721Semaste *
6254721Semaste * This code is derived from software contributed to The NetBSD Foundation
7254721Semaste * by David A. Holland.
8254721Semaste *
9254721Semaste * Redistribution and use in source and binary forms, with or without
10254721Semaste * modification, are permitted provided that the following conditions
11254721Semaste * are met:
12254721Semaste * 1. Redistributions of source code must retain the above copyright
13263363Semaste *    notice, this list of conditions and the following disclaimer.
14254721Semaste * 2. Redistributions in binary form must reproduce the above copyright
15254721Semaste *    notice, this list of conditions and the following disclaimer in the
16263363Semaste *    documentation and/or other materials provided with the distribution.
17254721Semaste *
18254721Semaste * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19263363Semaste * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20263363Semaste * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21254721Semaste * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22254721Semaste * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23254721Semaste * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24254721Semaste * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25263363Semaste * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26254721Semaste * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27254721Semaste * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28254721Semaste * POSSIBILITY OF SUCH DAMAGE.
29254721Semaste */
30
31#include <sys/cdefs.h>
32__RCSID("$NetBSD: quota_cursor.c,v 1.5 2012/02/01 05:34:40 dholland Exp $");
33
34#include <stdlib.h>
35#include <errno.h>
36
37#include <quota.h>
38#include "quotapvt.h"
39
40struct quotacursor *
41quota_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
105void
106quotacursor_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
119int
120quotacursor_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
135int
136quotacursor_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
152int
153quotacursor_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
170int
171quotacursor_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
184int
185quotacursor_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