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

Reply via email to