Module Name: src Committed By: dholland Date: Mon Jan 9 15:34:34 UTC 2012
Modified Files: src/lib/libquota: quota_proplib.c quota_schema.c quotapvt.h Log Message: Implement the schema-related functions, using proplib code from /usr/bin/quota. To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/lib/libquota/quota_proplib.c cvs rdiff -u -r1.1 -r1.2 src/lib/libquota/quota_schema.c cvs rdiff -u -r1.3 -r1.4 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/quota_proplib.c diff -u src/lib/libquota/quota_proplib.c:1.2 src/lib/libquota/quota_proplib.c:1.3 --- src/lib/libquota/quota_proplib.c:1.2 Mon Jan 9 15:32:38 2012 +++ src/lib/libquota/quota_proplib.c Mon Jan 9 15:34:34 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: quota_proplib.c,v 1.2 2012/01/09 15:32:38 dholland Exp $ */ +/* $NetBSD: quota_proplib.c,v 1.3 2012/01/09 15:34:34 dholland Exp $ */ /*- * Copyright (c) 2011 Manuel Bouyer * All rights reserved. @@ -26,10 +26,11 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: quota_proplib.c,v 1.2 2012/01/09 15:32:38 dholland Exp $"); +__RCSID("$NetBSD: quota_proplib.c,v 1.3 2012/01/09 15:34:34 dholland Exp $"); #include <string.h> #include <errno.h> +#include <err.h> #include <quota.h> #include "quotapvt.h" @@ -37,6 +38,131 @@ __RCSID("$NetBSD: quota_proplib.c,v 1.2 #include <quota/quotaprop.h> #include <quota/quota.h> +static int +__quota_proplib_getversion(struct quotahandle *qh, int8_t *version_ret) +{ + const char *idtype; + prop_dictionary_t dict, data, cmd; + prop_array_t cmds, blank, datas; + const char *cmdstr; + struct plistref pref; + int8_t error8; + + /* XXX does this matter? */ + idtype = ufs_quota_class_names[QUOTA_CLASS_USER]; + + /* + * XXX this should not crash out on error. But this is what + * the code this came from did... probably because it can just + * leak memory instead of needing the proper cleanup code. + */ + + dict = quota_prop_create(); + if (dict == NULL) { + err(1, "quota_getimplname: quota_prop_create"); + } + + cmds = prop_array_create(); + if (cmds == NULL) { + err(1, "quota_getimplname: prop_array_create"); + } + + blank = prop_array_create(); + if (blank == NULL) { + err(1, "quota_getimplname: prop_array_create"); + } + + if (!quota_prop_add_command(cmds, "get version", idtype, blank)) { + err(1, "quota_getimplname: quota_prop_add_command"); + } + + if (!prop_dictionary_set(dict, "commands", cmds)) { + err(1, "quota_getimplname: prop_dictionary_set"); + } + + if (prop_dictionary_send_syscall(dict, &pref) != 0) { + err(1, "quota_getimplname: prop_dictionary_send_syscall"); + } + + /* XXX don't we need prop_object_release(cmds) here too? */ + prop_object_release(dict); + + if (quotactl(qh->qh_mountpoint, &pref) != 0) + err(1, "quota_getimplname: quotactl"); + + if (prop_dictionary_recv_syscall(&pref, &dict) != 0) { + err(1, "quota_getimplname: prop_dictionary_recv_syscall"); + } + + if ((errno = quota_get_cmds(dict, &cmds)) != 0) { + err(1, "quota_getimplname: bad response (%s)", + "quota_get_cmds"); + } + + cmd = prop_array_get(cmds, 0); + if (cmd == NULL) { + err(1, "quota_getimplname: bad response (%s)", + "prop_array_get"); + } + + if (!prop_dictionary_get_cstring_nocopy(cmd, "command", &cmdstr)) { + err(1, "quota_getimplname: bad response (%s)", + "prop_dictionary_get_cstring_nocopy"); + } + + if (strcmp("get version", cmdstr) != 0) { + errx(1, "quota_getimplname: bad response (%s)", + "command name did not match"); + } + + if (!prop_dictionary_get_int8(cmd, "return", &error8)) { + err(1, "quota_getimplname: bad response (%s)", + "prop_dictionary_get_int8"); + } + + if (error8) { + /* this means the RPC action failed */ + prop_object_release(dict); + errno = error8; + return -1; + } + + datas = prop_dictionary_get(cmd, "data"); + if (datas == NULL) { + err(1, "quota_getimplname: bad response (%s)", + "prop_dictionary_get"); + } + + data = prop_array_get(datas, 0); + if (data == NULL) { + err(1, "quota_getimplname: bad response (%s)", + "prop_array_get"); + } + + if (!prop_dictionary_get_int8(data, "version", version_ret)) { + err(1, "quota_getimplname: bad response (%s)", + "prop_array_get_int8"); + } + + return 0; +} + +const char * +__quota_proplib_getimplname(struct quotahandle *qh) +{ + int8_t version; + + if (__quota_proplib_getversion(qh, &version) < 0) { + return NULL; + } + switch (version) { + case 1: return "ffs quota1"; + case 2: return "ffs quota2"; + default: break; + } + return "unknown"; +} + int __quota_proplib_get(struct quotahandle *qh, const struct quotakey *qk, struct quotaval *qv) Index: src/lib/libquota/quota_schema.c diff -u src/lib/libquota/quota_schema.c:1.1 src/lib/libquota/quota_schema.c:1.2 --- src/lib/libquota/quota_schema.c:1.1 Mon Jan 9 15:22:39 2012 +++ src/lib/libquota/quota_schema.c Mon Jan 9 15:34:34 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: quota_schema.c,v 1.1 2012/01/09 15:22:39 dholland Exp $ */ +/* $NetBSD: quota_schema.c,v 1.2 2012/01/09 15:34:34 dholland Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. * All rights reserved. @@ -29,54 +29,75 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: quota_schema.c,v 1.1 2012/01/09 15:22:39 dholland Exp $"); +__RCSID("$NetBSD: quota_schema.c,v 1.2 2012/01/09 15:34:34 dholland Exp $"); -#include <stddef.h> +#include <sys/types.h> +#include <sys/statvfs.h> +#include <stdlib.h> +#include <string.h> #include <errno.h> #include <quota.h> +#include <quota/quotaprop.h> +#include "quotapvt.h" + +/* + * Functions for getting information about idtypes and such. + */ -/* ARGSUSED */ const char * quota_getimplname(struct quotahandle *qh) { - errno = ENOSYS; - return NULL; + if (qh->qh_isnfs) { + /* XXX this should maybe report the rquotad protocol version */ + return "nfs via rquotad"; + } else { + return __quota_proplib_getimplname(qh); + } } /* ARGSUSED */ unsigned quota_getnumidtypes(struct quotahandle *qh) { - return 0; + return QUOTA_NCLASS; } /* ARGSUSED */ const char * quota_idtype_getname(struct quotahandle *qh, int idtype) { - errno = ENOSYS; - return NULL; + if (idtype < 0 || idtype >= QUOTA_NCLASS) { + return NULL; + } + return ufs_quota_class_names[idtype]; } /* ARGSUSED */ unsigned quota_getnumobjtypes(struct quotahandle *qh) { - return 0; + return QUOTA_NLIMITS; } /* ARGSUSED */ const char * quota_objtype_getname(struct quotahandle *qh, int objtype) { - errno = ENOSYS; - return NULL; + if (objtype < 0 || objtype >= QUOTA_NLIMITS) { + return NULL; + } + return ufs_quota_limit_names[objtype]; } /* ARGSUSED */ int quota_objtype_isbytes(struct quotahandle *qh, int objtype) { + switch (objtype) { + case QUOTA_LIMIT_BLOCK: return 1; + case QUOTA_LIMIT_FILE: return 0; + default: break; + } return 0; } Index: src/lib/libquota/quotapvt.h diff -u src/lib/libquota/quotapvt.h:1.3 src/lib/libquota/quotapvt.h:1.4 --- src/lib/libquota/quotapvt.h:1.3 Mon Jan 9 15:31:11 2012 +++ src/lib/libquota/quotapvt.h Mon Jan 9 15:34:34 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: quotapvt.h,v 1.3 2012/01/09 15:31:11 dholland Exp $ */ +/* $NetBSD: quotapvt.h,v 1.4 2012/01/09 15:34:34 dholland Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. * All rights reserved. @@ -36,6 +36,7 @@ struct quotahandle { }; /* proplib kernel interface */ +const char *__quota_proplib_getimplname(struct quotahandle *); int __quota_proplib_get(struct quotahandle *qh, const struct quotakey *qk, struct quotaval *qv);