Module Name: src Committed By: dholland Date: Mon Jan 9 15:31:12 UTC 2012
Modified Files: src/lib/libquota: getfsquota.c getnfsquota.c getufsquota.c quotapvt.h Log Message: Redo getfsquota() and getnfsquota() using the new API. Change the previous getufsquota() to __quota_getquota() and call it from all three functions: getfsquota(), getufsquota(), and getnfsquota(). To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 src/lib/libquota/getfsquota.c cvs rdiff -u -r1.4 -r1.5 src/lib/libquota/getnfsquota.c cvs rdiff -u -r1.5 -r1.6 src/lib/libquota/getufsquota.c cvs rdiff -u -r1.2 -r1.3 src/lib/libquota/quotapvt.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libquota/getfsquota.c diff -u src/lib/libquota/getfsquota.c:1.3 src/lib/libquota/getfsquota.c:1.4 --- src/lib/libquota/getfsquota.c:1.3 Fri Nov 25 16:55:05 2011 +++ src/lib/libquota/getfsquota.c Mon Jan 9 15:31:11 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: getfsquota.c,v 1.3 2011/11/25 16:55:05 dholland Exp $ */ +/* $NetBSD: getfsquota.c,v 1.4 2012/01/09 15:31:11 dholland Exp $ */ /*- * Copyright (c) 2011 Manuel Bouyer @@ -27,39 +27,20 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: getfsquota.c,v 1.3 2011/11/25 16:55:05 dholland Exp $"); +__RCSID("$NetBSD: getfsquota.c,v 1.4 2012/01/09 15:31:11 dholland Exp $"); -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <err.h> -#include <string.h> +#include <quota.h> +#include <quota/quota.h> -#include <sys/types.h> -#include <sys/statvfs.h> +#include "quotapvt.h" -#include <quota/quotaprop.h> -#include <quota/quota.h> -/* retrieve quotas with ufs semantics from vfs, for the given user id */ +/* + * "retrieve quotas with ufs semantics from vfs, for the given user id" + */ int getfsquota(const char *path, struct quotaval *qv, uid_t id, const char *class) { - struct statvfs v; - - if (statvfs(path, &v) < 0) { - return -1; - } - if (strcmp(v.f_fstypename, "nfs") == 0) - return getnfsquota(v.f_mntfromname, qv, id, class); - else { - if ((v.f_flag & ST_QUOTA) == 0) - return 0; - /* - * assume all quota-enabled local filesystems have UFS - * semantic for now - */ - return getufsquota(v.f_mntonname, qv, id, class); - } + return __quota_getquota(path, qv, id, class); } Index: src/lib/libquota/getnfsquota.c diff -u src/lib/libquota/getnfsquota.c:1.4 src/lib/libquota/getnfsquota.c:1.5 --- src/lib/libquota/getnfsquota.c:1.4 Fri Nov 25 16:55:05 2011 +++ src/lib/libquota/getnfsquota.c Mon Jan 9 15:31:11 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: getnfsquota.c,v 1.4 2011/11/25 16:55:05 dholland Exp $ */ +/* $NetBSD: getnfsquota.c,v 1.5 2012/01/09 15:31:11 dholland Exp $ */ /* * Copyright (c) 1980, 1990, 1993 @@ -42,170 +42,84 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 19 #if 0 static char sccsid[] = "@(#)quota.c 8.4 (Berkeley) 4/28/95"; #else -__RCSID("$NetBSD: getnfsquota.c,v 1.4 2011/11/25 16:55:05 dholland Exp $"); +__RCSID("$NetBSD: getnfsquota.c,v 1.5 2012/01/09 15:31:11 dholland Exp $"); #endif #endif /* not lint */ -/* - * Disk quota reporting program. - */ -#include <sys/param.h> #include <sys/types.h> -#include <sys/socket.h> - -#include <ctype.h> -#include <err.h> -#include <errno.h> -#include <netdb.h> -#include <stdio.h> +#include <sys/mount.h> #include <stdlib.h> #include <string.h> -#include <time.h> -#include <unistd.h> +#include <errno.h> +#include <quota.h> #include <quota/quota.h> -#include <quota/quotaprop.h> -#include <rpc/rpc.h> -#include <rpc/pmap_prot.h> -#include <rpcsvc/rquota.h> - -/* convert a rquota limit to our semantic */ -static uint64_t -rqlim2qlim(uint32_t lim) -{ - if (lim == 0) - return UQUAD_MAX; - else - return (lim - 1); -} - -static int -callaurpc(const char *host, rpcprog_t prognum, rpcvers_t versnum, - rpcproc_t procnum, xdrproc_t inproc, void *in, xdrproc_t outproc, void *out) -{ - struct sockaddr_in server_addr; - enum clnt_stat clnt_stat; - struct hostent *hp; - struct timeval timeout, tottimeout; - - CLIENT *client = NULL; - int sock = RPC_ANYSOCK; - - if ((hp = gethostbyname(host)) == NULL) - return (int) RPC_UNKNOWNHOST; - timeout.tv_usec = 0; - timeout.tv_sec = 6; - memmove(&server_addr.sin_addr, hp->h_addr, hp->h_length); - server_addr.sin_family = AF_INET; - server_addr.sin_port = 0; - - if ((client = clntudp_create(&server_addr, prognum, - versnum, timeout, &sock)) == NULL) - return (int) rpc_createerr.cf_stat; - - client->cl_auth = authunix_create_default(); - tottimeout.tv_sec = 25; - tottimeout.tv_usec = 0; - clnt_stat = clnt_call(client, procnum, inproc, in, - outproc, out, tottimeout); - - return (int) clnt_stat; -} +#include "quotapvt.h" int getnfsquota(const char *mp, struct quotaval *qv, uint32_t id, const char *class) { - struct getquota_args gq_args; - struct ext_getquota_args ext_gq_args; - struct getquota_rslt gq_rslt; - struct timeval tv; - char *host, *path; - int ret, rpcqtype; - - if (strcmp(class, QUOTADICT_CLASS_USER) == 0) - rpcqtype = RQUOTA_USRQUOTA; - else if (strcmp(class, QUOTADICT_CLASS_GROUP) == 0) - rpcqtype = RQUOTA_GRPQUOTA; - else { - errno = EINVAL; - return -1; - } + struct statvfs *mounts; + size_t size; + int nummounts, i, ret; + int serrno; /* - * must be some form of "hostname:/path" + * For some reason getnfsquota was defined so that the mount + * information passed in is the f_mntfromname (containing the + * remote host and path) from statvfs. The only way to convert + * this back to something generally useful is to search the + * available mounts for something that matches. Sigh. + * + * Note that we can't use getmntinfo(3) as the caller probably + * is and another use would potentially interfere. */ - path = strdup(mp); - if (path == NULL) { - errno = ENOMEM; + + nummounts = getvfsstat(NULL, (size_t)0, MNT_NOWAIT); + if (nummounts < 0) { return -1; } - host = strsep(&path, ":"); - if (path == NULL) { - free(host); - errno = EINVAL; + if (nummounts == 0) { + errno = ENOENT; return -1; } - - ext_gq_args.gqa_pathp = path; - ext_gq_args.gqa_id = id; - ext_gq_args.gqa_type = rpcqtype; - ret = callaurpc(host, RQUOTAPROG, EXT_RQUOTAVERS, - RQUOTAPROC_GETQUOTA, (xdrproc_t)xdr_ext_getquota_args, - &ext_gq_args, (xdrproc_t)xdr_getquota_rslt, &gq_rslt); - if (ret == RPC_PROGVERSMISMATCH && rpcqtype == RQUOTA_USRQUOTA) { - /* try RQUOTAVERS */ - gq_args.gqa_pathp = path; - gq_args.gqa_uid = id; - ret = callaurpc(host, RQUOTAPROG, RQUOTAVERS, - RQUOTAPROC_GETQUOTA, (xdrproc_t)xdr_getquota_args, - &gq_args, (xdrproc_t)xdr_getquota_rslt, &gq_rslt); - } - free(host); - - if (ret != RPC_SUCCESS) { - return 0; - } - - switch (gq_rslt.status) { - case Q_NOQUOTA: - break; - case Q_EPERM: - errno = EACCES; + size = nummounts * sizeof(mounts[0]); + mounts = malloc(size); + if (mounts == NULL) { + return -1; + } + nummounts = getvfsstat(mounts, size, MNT_NOWAIT); + if (nummounts < 0) { + serrno = errno; + free(mounts); + errno = serrno; return -1; - case Q_OK: - gettimeofday(&tv, NULL); + } - /* blocks*/ - qv[QUOTA_LIMIT_BLOCK].qv_hardlimit = rqlim2qlim( - gq_rslt.getquota_rslt_u.gqr_rquota.rq_bhardlimit * - (gq_rslt.getquota_rslt_u.gqr_rquota.rq_bsize / DEV_BSIZE)); - qv[QUOTA_LIMIT_BLOCK].qv_softlimit = rqlim2qlim( - gq_rslt.getquota_rslt_u.gqr_rquota.rq_bsoftlimit * - (gq_rslt.getquota_rslt_u.gqr_rquota.rq_bsize / DEV_BSIZE)); - qv[QUOTA_LIMIT_BLOCK].qv_usage = - gq_rslt.getquota_rslt_u.gqr_rquota.rq_curblocks * - (gq_rslt.getquota_rslt_u.gqr_rquota.rq_bsize / DEV_BSIZE); - qv[QUOTA_LIMIT_BLOCK].qv_expiretime = (tv.tv_sec + - gq_rslt.getquota_rslt_u.gqr_rquota.rq_btimeleft); - - /* inodes */ - qv[QUOTA_LIMIT_FILE].qv_hardlimit = rqlim2qlim( - gq_rslt.getquota_rslt_u.gqr_rquota.rq_fhardlimit); - qv[QUOTA_LIMIT_FILE].qv_softlimit = rqlim2qlim( - gq_rslt.getquota_rslt_u.gqr_rquota.rq_fsoftlimit); - qv[QUOTA_LIMIT_FILE].qv_usage = - gq_rslt.getquota_rslt_u.gqr_rquota.rq_curfiles; - qv[QUOTA_LIMIT_FILE].qv_expiretime = (int)(tv.tv_sec + - gq_rslt.getquota_rslt_u.gqr_rquota.rq_ftimeleft); - - qv[QUOTA_LIMIT_BLOCK].qv_grace = - qv[QUOTA_LIMIT_FILE].qv_grace = 0; - return 1; - default: - /* XXX sert errno and return -1 ? */ - break; + /* + * Note: if the size goes up, someone added a new mount; it + * can't be the one we're looking for. Assume it will end up + * at the end of the list so we don't need to refetch the + * info, and reset nummounts to avoid chugging off the end + * of the array. + */ + if (nummounts * sizeof(mounts[0]) > size) { + nummounts = size / sizeof(mounts[0]); } - return 0; + + for (i=0; i<nummounts; i++) { + if (!strcmp(mounts[i].f_mntfromname, mp)) { + ret = __quota_getquota(mounts[i].f_mntonname, + qv, id, class); + serrno = errno; + free(mounts); + errno = serrno; + return ret; + } + } + free(mounts); + errno = ENOENT; + return -1; } Index: src/lib/libquota/getufsquota.c diff -u src/lib/libquota/getufsquota.c:1.5 src/lib/libquota/getufsquota.c:1.6 --- src/lib/libquota/getufsquota.c:1.5 Mon Jan 9 15:28:31 2012 +++ src/lib/libquota/getufsquota.c Mon Jan 9 15:31:11 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: getufsquota.c,v 1.5 2012/01/09 15:28:31 dholland Exp $ */ +/* $NetBSD: getufsquota.c,v 1.6 2012/01/09 15:31:11 dholland Exp $ */ /*- * Copyright (c) 2011 Manuel Bouyer @@ -27,20 +27,17 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: getufsquota.c,v 1.5 2012/01/09 15:28:31 dholland Exp $"); +__RCSID("$NetBSD: getufsquota.c,v 1.6 2012/01/09 15:31:11 dholland Exp $"); -#include <sys/types.h> -#include <stdio.h> -#include <stdlib.h> #include <string.h> #include <errno.h> -#include <err.h> -#include <quota/quotaprop.h> #include <quota/quota.h> - +#include <quota/quotaprop.h> /* for QUOTADICT_CLASS_* strings */ #include <quota.h> +#include "quotapvt.h" + /* * Return true if QV contains any actual information. * @@ -68,15 +65,15 @@ quotaval_nonempty(const struct quotaval * contains, fetch both block and file quotas and store them in QV, * namely in qv[0] and qv[1] respectively. */ + int -getufsquota(const char *mp, struct quotaval *qv, uid_t id, +__quota_getquota(const char *path, struct quotaval *qv, uid_t id, const char *class) { -#if 1 struct quotakey qk; struct quotahandle *qh; - qh = quota_open(mp); + qh = quota_open(path); if (qh == NULL) { return -1; } @@ -114,6 +111,14 @@ getufsquota(const char *mp, struct quota } return 0; +} + +int +getufsquota(const char *mp, struct quotaval *qv, uid_t id, + const char *class) +{ +#if 1 + return __quota_getquota(mp, qv, id, class); #else /* old code for reference */ prop_dictionary_t dict, data, cmd; Index: src/lib/libquota/quotapvt.h diff -u src/lib/libquota/quotapvt.h:1.2 src/lib/libquota/quotapvt.h:1.3 --- src/lib/libquota/quotapvt.h:1.2 Mon Jan 9 15:29:56 2012 +++ src/lib/libquota/quotapvt.h Mon Jan 9 15:31:11 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: quotapvt.h,v 1.2 2012/01/09 15:29:56 dholland Exp $ */ +/* $NetBSD: quotapvt.h,v 1.3 2012/01/09 15:31:11 dholland Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. * All rights reserved. @@ -43,3 +43,7 @@ int __quota_proplib_get(struct quotahand int __quota_nfs_get(struct quotahandle *qh, const struct quotakey *qk, struct quotaval *qv); +/* compat for old library */ +int __quota_getquota(const char *path, struct quotaval *qv, uid_t id, + const char *class); +