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);