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 * 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 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 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 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 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 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 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