$NetBSD: patch-at,v 1.5.4.1 2011/08/30 17:42:23 tron Exp $

--- etc/afpd/quota.c.orig	2011-03-24 15:43:48.000000000 +0100
+++ etc/afpd/quota.c	2011-03-24 17:56:34.000000000 +0100
@@ -47,6 +47,96 @@
 #include "volume.h"
 #include "unix.h"
 
+#ifdef HAVE_LIBQUOTA
+#include <quota/quota.h>
+
+static int
+getfreespace(struct vol *vol, VolSpace *bfree, VolSpace *btotal,
+    uid_t ouruid, uid_t quid, const char *classq)
+{
+	int retq;
+	struct ufs_quota_entry ufsq[QUOTA_NLIMITS];
+	time_t now;
+
+	if (time(&now) == -1) {
+		LOG(log_info, logtype_afpd, "time(): %s",
+		    strerror(errno));
+		return -1;
+	}
+
+	if ( seteuid( getuid() ) != 0 )  {
+		LOG(log_info, logtype_afpd, "seteuid(): %s",
+		    strerror(errno));
+		return -1;
+	}
+	if ((retq = getfsquota(vol->v_path, ufsq, quid, classq)) < 0) {
+		LOG(log_info, logtype_afpd, "getfsquota(%s, %s): %s",
+		    vol->v_path, classq, strerror(errno));
+	}
+        seteuid( ouruid );
+	if (retq < 1)
+		return retq;
+
+	switch(QL_STATUS(quota_check_limit(ufsq[QUOTA_LIMIT_BLOCK].ufsqe_cur, 1,
+	    ufsq[QUOTA_LIMIT_BLOCK].ufsqe_softlimit,
+	    ufsq[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit,
+	    ufsq[QUOTA_LIMIT_BLOCK].ufsqe_time, now))) {
+	case QL_S_DENY_HARD:
+	case QL_S_DENY_GRACE:
+		*bfree = 0;
+		*btotal = dbtob(ufsq[QUOTA_LIMIT_BLOCK].ufsqe_cur);
+		break;
+	default:
+		*bfree = dbtob(ufsq[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit -
+		    ufsq[QUOTA_LIMIT_BLOCK].ufsqe_cur);
+		*btotal = dbtob(ufsq[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit);
+		break;
+	}
+	return 1;
+}
+
+int uquota_getvolspace( struct vol *vol, VolSpace *bfree, VolSpace *btotal, const u_int32_t bsize)
+{
+	int uretq, gretq;
+	VolSpace ubfree, ubtotal;
+	VolSpace gbfree, gbtotal;
+
+	uretq = getfreespace(vol, &ubfree, &ubtotal, uuid,
+	    uuid, QUOTADICT_CLASS_USER);
+	LOG(log_info, logtype_afpd, "getfsquota(%s): %d %d",
+	    vol->v_path, (int)ubfree, (int)ubtotal);
+	if (ngroups >= 1) {
+		gretq = getfreespace(vol, &ubfree, &ubtotal, uuid,
+		    groups[0], QUOTADICT_CLASS_GROUP);
+	} else
+		gretq = -1;
+	if (uretq < 1 && gretq < 1) { /* no quota for this fs */
+		return AFPERR_PARAM;
+	}
+	if (uretq < 1) {
+		/* use group quotas */
+		*bfree = gbfree;
+		*btotal = gbtotal;
+	} else if (gretq < 1) {
+		/* use user quotas */
+		*bfree = ubfree;
+		*btotal = ubtotal;
+	} else {
+		/* return smallest remaining space of user and group */
+		if (ubfree < gbfree) {
+			*bfree = ubfree;
+			*btotal = ubtotal;
+		} else {
+			*bfree = gbfree;
+			*btotal = gbtotal;
+		}
+	}
+	return AFP_OK;
+
+}
+
+#else /* HAVE_LIBQUOTA */
+
 /*
 #define DEBUG_QUOTA 0
 */
@@ -739,4 +829,5 @@
 
 	return( AFP_OK );
 }
+#endif /* HAVE_LIBQUOTA */
 #endif
